<?php declare(strict_types=1);
namespace Ott\CmsAdvanced\Subscriber;
use Doctrine\DBAL\Connection;
use Shopware\Core\Content\Cms\CmsPageEntity;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\Struct\ArrayStruct;
use Shopware\Storefront\Page\Navigation\NavigationPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class NavigationPageSubscriber implements EventSubscriberInterface
{
private Connection $connection;
private EntityRepositoryInterface $mediaRepository;
public function __construct(
Connection $connection,
EntityRepositoryInterface $mediaRepository
)
{
$this->connection = $connection;
$this->mediaRepository = $mediaRepository;
}
public static function getSubscribedEvents(): array
{
return [
NavigationPageLoadedEvent::class => 'onNavigationPageLoaded',
];
}
public function onNavigationPageLoaded(NavigationPageLoadedEvent $event): void
{
$cmsPage = $event->getPage()->getCmsPage();
if (null !== $cmsPage && $this->shouldExtendPage($cmsPage)) {
$navigationPage = $event->getPage();
$navigationId = $navigationPage->getNavigationId();
$statement = <<<'SQL'
SELECT
*
FROM
(SELECT LOWER(HEX(c.id)) AS categoryId, LOWER(HEX(m.id)) AS media
FROM category AS c
JOIN product_category AS pc ON c.id = pc.category_id
JOIN product_media AS pm ON pm.product_id = pc.product_id
JOIN media AS m ON m.id = pm.media_id
WHERE parent_id = UNHEX(:navigationId)
ORDER BY c.id ASC) AS result
GROUP BY categoryId
SQL;
$preparedStatement = $this->connection->prepare($statement);
$preparedStatement->bindValue('navigationId', $navigationId, \PDO::PARAM_STR);
$preparedStatement->execute();
$result = $preparedStatement->fetchAll();
if (!empty($result)) {
$mediaIds = [];
foreach ($result as $category) {
$mediaIds[] = $category['media'];
}
if (!empty($mediaIds)) {
$mediaCollection = $this->mediaRepository->search(
new Criteria($mediaIds),
$event->getContext()
)->getEntities();
if (!empty($mediaCollection)) {
$mediaUrls = [];
foreach ($mediaCollection->getElements() as $media) {
$mediaUrl = $media->getUrl();
if (!empty($media->getThumbnails())) {
foreach ($media->getThumbnails() as $thumbnail) {
if (400 === $thumbnail->getHeight() && 400 === $thumbnail->getWidth()) {
$mediaUrl = $thumbnail->getUrl();
break;
}
}
}
$mediaUrls[] = $mediaUrl;
}
foreach ($mediaUrls as $key => $mediaUrl) {
$result[$key]['media'] = $mediaUrl;
}
$navigationPage->addExtension('subcategoriesFirstProductImg', new ArrayStruct([
'data' => $result,
]));
}
}
}
}
}
private function shouldExtendPage(CmsPageEntity $cmsPage): bool
{
if (null !== $cmsPage->getSections()) {
foreach ($cmsPage->getSections() as $section) {
foreach ($section->getBlocks() as $block) {
foreach ($block->getSlots()->getElements() as $slot) {
if (
'categoryteaser' === $slot->getType()
&& null !== $slot->getConfig()
&& !empty($slot->getConfig()['useFirstProductImg'])
&& $slot->getConfig()['useFirstProductImg']['value']
) {
return true;
}
}
}
}
}
return false;
}
}