<?php declare(strict_types=1);
namespace LogBchange\Subscriber;
use LogBchange\Service\HighlightPropertyService;
use Shopware\Core\Content\Cms\CmsPageCollection;
use Shopware\Core\Content\Cms\SalesChannel\SalesChannelCmsPageLoaderInterface;
use Shopware\Core\Content\Media\MediaCollection;
use Shopware\Core\Content\Product\Events\ProductCrossSellingIdsCriteriaEvent;
use Shopware\Core\Content\Product\ProductEntity;
use Shopware\Core\Content\Product\SalesChannel\CrossSelling\CrossSellingElement;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Storefront\Page\Product\ProductPage;
use Shopware\Storefront\Page\Product\ProductPageCriteriaEvent;
use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
class ProductPageSubscriber implements EventSubscriberInterface
{
private EntityRepositoryInterface $mediaRepository;
private SalesChannelCmsPageLoaderInterface $cmsPageLoader;
private HighlightPropertyService $highlightPropertyService;
public function __construct(EntityRepositoryInterface $mediaRepository, SalesChannelCmsPageLoaderInterface $cmsPageLoader, HighlightPropertyService $highlightPropertyService)
{
$this->mediaRepository = $mediaRepository;
$this->cmsPageLoader = $cmsPageLoader;
$this->highlightPropertyService = $highlightPropertyService;
}
public static function getSubscribedEvents(): array
{
return [
ProductPageCriteriaEvent::class => 'onProductPageCriteria',
ProductPageLoadedEvent::class => 'onProductPageLoaded',
ProductCrossSellingIdsCriteriaEvent::class => 'onProductCrossSellingIdsCriteria',
];
}
public function onProductPageCriteria(ProductPageCriteriaEvent $event): void
{
$event->getCriteria()->addAssociation('properties.media');
}
public function onProductPageLoaded(ProductPageLoadedEvent $event): void
{
$page = $event->getPage();
$context = $event->getContext();
$request = $event->getRequest();
$saleChannelContext = $event->getSalesChannelContext();
$this->enrichHighlightProperties($page);
$this->enrichSidebarMedia($page, $context);
$this->enrichSocialMediaImages($page, $context);
$this->enrichCmsPageLayout($page, $saleChannelContext, $request);
}
public function onProductCrossSellingIdsCriteria(ProductCrossSellingIdsCriteriaEvent $event): void
{
$criteria = $event->getCriteria();
$criteria->addAssociation('properties.group');
}
private function enrichHighlightProperties(ProductPage $page): void
{
$product = $page->getProduct();
$crossSellings = $page->getCrossSellings();
$this->highlightPropertyService->enrichHighlightProperties($product);
/** @var CrossSellingElement $crossSelling */
foreach ($crossSellings as $crossSelling) {
/** @var ProductEntity $product */
foreach ($crossSelling->getProducts() as $product) {
$this->highlightPropertyService->enrichHighlightProperties($product);
}
}
}
private function enrichSidebarMedia(ProductPage $page, Context $context): void
{
$product = $page->getProduct();
$sidebarMediaIds = array_filter([
$product->getCustomFields()['custom_product_fields_extra_image1'] ?? null,
$product->getCustomFields()['custom_product_fields_extra_image2'] ?? null,
$product->getCustomFields()['custom_product_fields_extra_image3'] ?? null,
]);
$sidebarMedia = $sidebarMediaIds ? $this->mediaRepository->search(new Criteria($sidebarMediaIds), $context)->getEntities() : new MediaCollection();
$product->addExtension('sidebarMedia', $sidebarMedia);
}
private function enrichSocialMediaImages(ProductPage $page, Context $context): void
{
$product = $page->getProduct();
$socialMediaImageFacebookId = $product->getCustomFields()['custom_social_media_images_facebook_de'] ?? null;
$socialMediaImageTwitterId = $product->getCustomFields()['custom_social_media_images_twitter_de'] ?? null;
$socialMediaImageIds = array_filter([
$socialMediaImageFacebookId,
$socialMediaImageTwitterId,
]);
$socialMediaImages = $socialMediaImageIds ? $this->mediaRepository->search(new Criteria($socialMediaImageIds), $context)->getEntities() : new MediaCollection();
$product->addArrayExtension('socialMediaImages', [
'facebook' => $socialMediaImages->get($socialMediaImageFacebookId),
'twitter' => $socialMediaImages->get($socialMediaImageTwitterId),
]);
}
private function enrichCmsPageLayout(ProductPage $page, SalesChannelContext $context, Request $request): void
{
$product = $page->getProduct();
$cmsPageID = $product->getCustomFields()['custom_product_fields_landing_page'] ?? null;
if($cmsPageID){
$pages = $this->cmsPageLoader->load(
$request,
$this->createCriteria($cmsPageID, $request),
$context,
null,
null
);
if($pages->has($cmsPageID)){
$product->addArrayExtension('landingPageLayout', [
'landingPage' => $pages->get($cmsPageID)
]);
}
}
else {
$product->addArrayExtension('landingPageLayout', [
'landingPage' => null
]);
}
/* $layoutIDs = array_filter([$layoutID]);
$cmsPageLayout = $layoutIDs ? $this->cmsPageLoader->search(new Criteria($layoutIDs), $context)->get($layoutID) : new CmsPageCollection();
echo print_r("landing page => " . $cmsPageLayout->getSections(), true);
$product->addArrayExtension('landingPageLayout', [
'landingPage' => $cmsPageLayout
]);*/
}
private function createCriteria(string $pageId, Request $request): Criteria
{
$criteria = new Criteria([$pageId]);
$criteria->setTitle('landing-page::cms-page');
$slots = $request->get('slots');
if (\is_string($slots)) {
$slots = explode('|', $slots);
}
if (!empty($slots) && \is_array($slots)) {
$criteria
->getAssociation('sections.blocks')
->addFilter(new EqualsAnyFilter('slots.id', $slots));
}
return $criteria;
}
}