<?php declare(strict_types=1);
namespace DISco\GA4\Subscriber;
use Exception;
use Shopware\Core\Checkout\Cart\LineItem\LineItemCollection;
use Shopware\Core\Content\Cms\SalesChannel\Struct\CrossSellingStruct;
use Shopware\Core\Content\Cms\SalesChannel\Struct\ProductBoxStruct;
use Shopware\Core\Content\Cms\SalesChannel\Struct\ProductListingStruct;
use Shopware\Core\Content\Cms\SalesChannel\Struct\ProductSliderStruct;
use Shopware\Core\Content\Product\Events\ProductListingCriteriaEvent;
use Shopware\Core\Content\Product\Events\ProductListingResultEvent;
use Shopware\Core\Framework\DataAbstractionLayer\EntityCollection;
use Shopware\Storefront\Page\Checkout\Cart\CheckoutCartPageLoadedEvent;
use Shopware\Storefront\Page\Checkout\Confirm\CheckoutConfirmPageLoadedEvent;
use Shopware\Storefront\Page\Checkout\Finish\CheckoutFinishPageLoadedEvent;
use Shopware\Storefront\Page\Checkout\Offcanvas\OffcanvasCartPageLoadedEvent;
use Shopware\Storefront\Page\Navigation\NavigationPageLoadedEvent;
use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
use Shopware\Storefront\Page\Search\SearchPageLoadedEvent;
use Shopware\Storefront\Page\Wishlist\WishlistPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class FrontendSubscriber implements EventSubscriberInterface
{
public function __construct()
{
}
public static function getSubscribedEvents(): array
{
// Return the events to listen to as array like this: <event to listen to> => <method to execute>
return [
ProductListingCriteriaEvent::class => 'onProductListingCriteria',
SearchPageLoadedEvent::class => 'onSearchPageLoadedEvent',
ProductPageLoadedEvent::class => 'onProductPageLoadedEvent',
NavigationPageLoadedEvent::class => 'onNavigationPageLoadedEvent',
CheckoutCartPageLoadedEvent::class => 'onCheckoutCartPageLoadedEvent',
CheckoutConfirmPageLoadedEvent::class => 'onCheckoutConfirmPageLoadedEvent',
CheckoutFinishPageLoadedEvent::class => 'onCheckoutFinishPageLoadedEvent',
WishlistPageLoadedEvent::class => 'onWishlistPageLoadedEvent',
OffcanvasCartPageLoadedEvent::class => 'onOffcanvasCartPageLoadedEvent'
];
}
public function onOffcanvasCartPageLoadedEvent(OffcanvasCartPageLoadedEvent $event): bool
{
try {
$elements = $event->getPage()->getCart()->getLineItems()->getElements();
if (!empty($elements)) {
$collection = array_filter($elements);
$disGA4Extension = new LineItemCollection($collection);
$event->getContext()->addExtension('disGA4LineItemsExtension', $disGA4Extension);
}
} catch (Exception $e) {
}
return true;
}
public function onProductListingCriteria(ProductListingCriteriaEvent $event): bool
{
$event->getCriteria()->addAssociation('categories');
$event->getCriteria()->addAssociation('seoCategory');
$event->getCriteria()->addAssociation('manufacturer');
return true;
}
public function onProductListingResultEvent(ProductListingResultEvent $event): bool
{
try {
$elements = [];
foreach ($event->getResult()->getElements() as $product) {
$elements[] = $product;
}
if (!empty($elements)) {
$collection = array_filter($elements);
$disGA4Extension = new EntityCollection($collection);
$event->getContext()->addExtension('disGA4ProductsExtension', $disGA4Extension);
}
} catch (Exception $e) {
}
return true;
}
public function onWishlistPageLoadedEvent(WishlistPageLoadedEvent $event): bool
{
try {
$elements = $event->getPage()->getWishlist()->getProductListing()->getElements();
if (!empty($elements)) {
$collection = array_filter($elements);
$disGA4Extension = new EntityCollection($collection);
$event->getContext()->addExtension('disGA4ProductsExtension', $disGA4Extension);
}
} catch (Exception $e) {
}
return true;
}
public function onSearchPageLoadedEvent(SearchPageLoadedEvent $event): bool
{
try {
$elements = $event->getPage()->getListing()->getElements();
if (!empty($elements)) {
$collection = array_filter($elements);
$disGA4Extension = new EntityCollection($collection);
$event->getContext()->addExtension('disGA4ProductsExtension', $disGA4Extension);
}
} catch (Exception $e) {
}
return true;
}
public function onProductPageLoadedEvent(ProductPageLoadedEvent $event): bool
{
try {
$elements = [$event->getPage()->getProduct()];
$cmsList = ['product-box', 'product-slider', 'cross-selling'];
if ($event->getPage()->getProduct()->getCmsPage()) {
try {
$cmsElements = $event->getPage()->getCmsPage()->getSections()->getBlocks()->getSlots()->getElements();
foreach ($cmsElements as $key => $object) {
if (!in_array($object->getType(), $cmsList)) {
unset($cmsElements[$key]);
}
}
foreach ($cmsElements as $object) {
$data = $object->getData();
switch ($data) {
case $data instanceof CrossSellingStruct:
if ($data->getCrossSellings()) {
foreach ($data->getCrossSellings()->getElements() as $crossSelling) {
foreach ($crossSelling->getProducts() as $product) {
$elements[] = $product;
}
}
}
break;
case $data instanceof ProductBoxStruct:
$elements[] = $data->getProduct();
break;
case $data instanceof ProductSliderStruct :
foreach ($data->getProducts() as $product) {
$elements[] = $product;
}
break;
case $data instanceof ProductListingStruct:
foreach ($data->getListing()->getEntities() as $product) {
$elements[] = $product;
}
break;
}
}
} catch (Exception $e) {
}
} else {
$crossSellings = $event->getPage()->getCrossSellings();
if (!empty($crossSellings->getElements())) {
$crossSellingsElements = $crossSellings->getElements();
foreach ($crossSellingsElements as $crossSellingsElement) {
foreach ($crossSellingsElement->getProducts() as $product) {
$elements[] = $product;
}
}
}
}
if (!empty($elements)) {
$collection = array_filter($elements);
$disGA4Extension = new EntityCollection($collection);
$event->getContext()->addExtension('disGA4ProductsExtension', $disGA4Extension);
}
} catch (Exception $e) {
}
return true;
}
public function onNavigationPageLoadedEvent(NavigationPageLoadedEvent $event): bool
{
$cmsList = ['product-box', 'product-listing', 'product-slider', 'cross-selling'];
$elements = [];
try {
$cmsElements = $event->getPage()->getCmsPage()->getSections()->getBlocks()->getSlots()->getElements();
foreach ($cmsElements as $key => $object) {
if (!in_array($object->getType(), $cmsList)) {
unset($cmsElements[$key]);
}
}
foreach ($cmsElements as $object) {
$data = $object->getData();
switch ($data) {
case $data instanceof CrossSellingStruct:
if ($data->getCrossSellings()) {
foreach ($data->getCrossSellings()->getElements() as $crossSelling) {
foreach ($crossSelling->getProducts() as $product) {
$elements[] = $product;
}
}
}
break;
case $data instanceof ProductBoxStruct:
$elements[] = $data->getProduct();
break;
case $data instanceof ProductSliderStruct :
foreach ($data->getProducts() as $product) {
$elements[] = $product;
}
break;
case $data instanceof ProductListingStruct:
if ($data->getListing()) {
foreach ($data->getListing()->getEntities() as $product) {
$elements[] = $product;
}
}
break;
}
}
if ($event->getPage()->getCmsPage()->getProducts()) {
foreach ($event->getPage()->getCmsPage()->getProducts() as $product) {
$elements[] = $product;
}
}
if (!empty($elements)) {
$collection = array_filter($elements);
$disGA4Extension = new EntityCollection($collection);
$event->getContext()->addExtension('disGA4ProductsExtension', $disGA4Extension);
}
} catch (Exception $e) {
}
return true;
}
public function onCheckoutCartPageLoadedEvent(CheckoutCartPageLoadedEvent $event): bool
{
try {
$elements = $event->getPage()->getCart()->getLineItems()->getElements();
if (!empty($elements)) {
$collection = array_filter($elements);
$disGA4Extension = new LineItemCollection($collection);
$event->getContext()->addExtension('disGA4LineItemsExtension', $disGA4Extension);
}
} catch (Exception $e) {
}
return true;
}
public function onCheckoutConfirmPageLoadedEvent(CheckoutConfirmPageLoadedEvent $event): bool
{
try {
$elements = $event->getPage()->getCart()->getLineItems()->getElements();
if (!empty($elements)) {
$collection = array_filter($elements);
$disGA4Extension = new LineItemCollection($collection);
$event->getContext()->addExtension('disGA4LineItemsExtension', $disGA4Extension);
}
} catch (Exception $e) {
}
return true;
}
public function onCheckoutFinishPageLoadedEvent(CheckoutFinishPageLoadedEvent $event): bool
{
try {
$elements = $event->getPage()->getOrder()->getLineItems()->getElements();
if (!empty($elements)) {
$collection = array_filter($elements);
$disGA4Extension = new LineItemCollection($collection);
$event->getContext()->addExtension('disGA4LineItemsExtension', $disGA4Extension);
}
} catch (Exception $e) {
}
return true;
}
}