<?php declare(strict_types=1);
namespace Flink\CmsGridBuilder\Subscriber;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Storefront\Event\StorefrontRenderEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Shopware\Core\Content\Cms\Events\CmsPageLoadedEvent;
class CmsPageSubscriber implements EventSubscriberInterface
{
protected $cmsGridRepository = null;
public function __construct(
EntityRepository $cmsGridRepository
)
{
$this->cmsGridRepository = $cmsGridRepository;
}
public static function getSubscribedEvents()
{
return [
CmsPageLoadedEvent::class => 'onCmsPageLoaded',
StorefrontRenderEvent::class => 'onStorefrontRender'
];
}
public function onCmsPageLoaded(CmsPageLoadedEvent $event)
{
$entities = $event->getResult()->getElements();
$this->_addCmsGridsToBlocks($entities, $event->getContext());
array_walk($entities, function($cmsPage) { $cmsPage->flinkCmsGridsAdded = true; });
}
public function onStorefrontRender(StorefrontRenderEvent $event)
{
$parameters = $event->getParameters();
if (@is_object($parameters['page']) && method_exists($parameters['page'], 'getCmsPage')) {
$cmsPage = $parameters['page']->getCmsPage();
if ($cmsPage) {
$this->_addCmsGridsToBlocks([$cmsPage], $event->getContext());
$cmsPage->flinkCmsGridsAdded = true;
}
}
}
private function _addCmsGridsToBlocks($cmsPages, $context)
{
$gridBlocks = $this->_getGridBlocks($cmsPages);
$cmsGrids = $this->_getCmsGrids($gridBlocks, $context);
foreach ($cmsGrids as $cmsGrid) {
if (isset($gridBlocks[$cmsGrid->getId()])) {
foreach ($gridBlocks[$cmsGrid->getId()] as $gridBlock) {
$customFields = $gridBlock->getCustomFields();
$customFields['flinkCmsGrid'] = $cmsGrid;
$gridBlock->setCustomFields($customFields);
}
}
}
}
private function _getGridBlocks($cmsPages)
{
$gridBlocks = [];
foreach ($cmsPages as $cmsPage) {
if (empty($cmsPage->flinkCmsGridsAdded)) {
foreach ($cmsPage->getSections() as $section) {
foreach ($section->getBlocks() as $block) {
if (strpos($block->getType(), 'flink-cms-grid') === 0) {
$cmsGridId = str_replace('flink-cms-grid-', '', $block->getType());
if (!isset($gridBlocks[$cmsGridId])) {
$gridBlocks[$cmsGridId] = [];
}
$gridBlocks[$cmsGridId][] = $block;
}
}
}
}
}
return $gridBlocks;
}
private function _getCmsGrids($gridBlocks, $context)
{
if (!$gridBlocks) {
return [];
}
$criteria = new Criteria(array_keys($gridBlocks));
return $this->cmsGridRepository->search($criteria, $context);
}
}