<?php declare(strict_types=1);
namespace ThemeOkeOnline\Storefront\CmsPage\Subscriber;
use Shopware\Core\Content\Cms\Events\CmsPageLoadedEvent;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\ContainsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\Struct\ArrayEntity;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class CmsPageLoadedSubscriber implements EventSubscriberInterface
{
/**
* @var EntityRepository
*/
private $categoryRepository;
/**
* @var CmsPageLoadedEvent
*/
private $event;
private $context;
public function __construct(EntityRepository $categoryRepository)
{
$this->categoryRepository = $categoryRepository;
}
public static function getSubscribedEvents(): array
{
return [
CmsPageLoadedEvent::class => ['cmsPageLoaded']
];
}
public function cmsPageLoaded(CmsPageLoadedEvent $event): void
{
$this->addCategoryDataToCMSPage($event);
$this->addSubcategoryDataToCMSPage($event);
}
public function addCategoryDataToCMSPage(CmsPageLoadedEvent $event)
{
$this->context = $event->getSalesChannelContext()->getContext();
$cmsPage = $event->getResult()->first();
$criteria = new Criteria();
$criteria->addAssociation('media');
$criteria->addFilter(
new EqualsFilter('active', true),
);
$categories = $this->categoryRepository->search(
$criteria,
$this->context
);
$cmsPage->addExtension(
'categories',
$categories->getEntities()
);
}
public function addSubcategoryDataToCMSPage(CmsPageLoadedEvent $event)
{
$this->context = $event->getSalesChannelContext()->getContext();
$cmsPage = $event->getResult()->first();
$listingElements = $cmsPage->getElementsOfType('product-listing');
if(sizeof($listingElements) <= 0) return;
$listing = $listingElements[0]->getData()->getListing();
$currentCategoryId = $listing->getCurrentFilters()['navigationId'];
$currentCategory = $this->getCategory($currentCategoryId);
$baseCategoryId = $this->getBaseCategoryOf($currentCategory);
$criteria = new Criteria();
$criteria->addAssociation('media');
$criteria->addFilter(
//new EqualsFilter('level', '4'), //Default was 4, filtering is now done by cms-component.
new EqualsFilter('active', true),
new ContainsFilter('path', $baseCategoryId)
);
$subcategories = $this->categoryRepository->search(
$criteria,
$this->context
);
$cmsPage->addExtension(
'subcategories',
$subcategories->getEntities()
);
$cmsPage->addExtension(
'subcategorymetadata',
new ArrayEntity([
'baseCategory' => $baseCategoryId,
'currentCategory' => $currentCategoryId,
'currentLevel' => $currentCategory->level
])
);
}
private function getBaseCategoryOf($category) {
if($category->getLevel() <= 2)
return $category->id;
return $this->getParentCategoryOf($category);
}
private function getParentCategoryOf($input) {
return preg_split('/\|/', $input->getPath(),-1, PREG_SPLIT_NO_EMPTY)[1];
}
private function getCategory($categoryId) {
$criteria = new Criteria();
$criteria->addFilter(
new EqualsFilter('id', $categoryId)
);
return $this->categoryRepository->search(
$criteria,
$this->context
)->getElements()[$categoryId];
}
}