<?php
namespace Crehler\FastNavigation\Subscriber;
use Crehler\FastNavigation\Service\NavigationService;
use Crehler\FastNavigation\Service\ProductService;
use Shopware\Core\Content\Product\Events\ProductListingResultEvent;
use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Session\Session;
class FrontendSubscriber implements EventSubscriberInterface
{
const SESSION_FAST_NAVIGATION = 'FastNavigation';
const SESSION_LAST_VISITED_CATEGORY = 'LastVisitedCategory';
/**
* @var Session
*/
private $session;
/**
* @var NavigationService;
*/
private $navigationService;
/**
* @var ProductService
*/
private $productService;
/**
* FrontendSubscriber constructor.
* @param Session $session
* @param NavigationService $navigationService
* @param ProductService $productService
*/
public function __construct(Session $session, NavigationService $navigationService, ProductService $productService)
{
$this->session = $session;
$this->navigationService = $navigationService;
$this->productService = $productService;
}
/**
* @return array
*/
public static function getSubscribedEvents() :array
{
return [
ProductListingResultEvent::class => 'onProductListingResultEvent',
ProductPageLoadedEvent::class => 'onProductPageLoadedEvent',
];
}
/**
* @param ProductListingResultEvent $event
*/
public function onProductListingResultEvent(ProductListingResultEvent $event)
{
$navigationID = $event->getResult()->getCurrentFilter('navigationId');
$this->session->set(self::SESSION_LAST_VISITED_CATEGORY, $navigationID);
$session = $this->session->get(self::SESSION_FAST_NAVIGATION);
$elements = $event->getResult()->getElements();
$navigationProducts = [];
if($session !== null)
{
$navigationProducts = $session;
}
unset($navigationProducts[$navigationID]);
foreach ($elements as $element){
$navigationProducts[$navigationID][] = $element->getId();
}
$this->session->set(self::SESSION_FAST_NAVIGATION, $navigationProducts);
}
/**
* @param ProductPageLoadedEvent $event
*/
public function onProductPageLoadedEvent(ProductPageLoadedEvent $event)
{
$productID = $event->getPage()->getProduct()->getId();
$lastVisitedCategory = $this->session->get(self::SESSION_LAST_VISITED_CATEGORY);
$navigationProducts = $this->session->get(self::SESSION_FAST_NAVIGATION);
if(!in_array($lastVisitedCategory, $event->getPage()->getProduct()->getCategoryTree())) {
$lastVisitedCategory = null;
}
if(!empty($navigationProducts) && isset($navigationProducts[$lastVisitedCategory])) {
$navigationProducts = $navigationProducts[$lastVisitedCategory];
$this->navigationService->setArray($navigationProducts);
$prevProduct = $this->navigationService->prev($productID);
$nextProduct = $this->navigationService->next($productID);
if($prevProduct) {
$event->getPage()->addExtension(
'ProductNavigation',
$event->getPage()->assign([
'prevProduct' => $prevProduct
])
);
}
if($nextProduct) {
$event->getPage()->addExtension(
'ProductNavigation',
$event->getPage()->assign([
'nextProduct' => $nextProduct
])
);
}
}else{
$productCategoryTreeID = $event->getPage()->getProduct()->getCategoryTree();
$productCategoryID = $productCategoryTreeID[1];
$navigationProducts = $this->productService->getProducts($productCategoryID);
$this->navigationService->setArray($navigationProducts);
$prevProduct = $this->navigationService->prev($productID);
$nextProduct = $this->navigationService->next($productID);
if($prevProduct) {
$event->getPage()->addExtension(
'ProductNavigation',
$event->getPage()->assign([
'prevProduct' => $prevProduct
])
);
}
if($nextProduct) {
$event->getPage()->addExtension(
'ProductNavigation',
$event->getPage()->assign([
'nextProduct' => $nextProduct
])
);
}
}
}
}