<?php declare(strict_types=1);
namespace Crehler\AdditionalArticle\Subscriber;
use Crehler\AdditionalArticle\Service\AdditionalArticlesService;
use Crehler\AdditionalArticle\Struct\AdditionalArticleStruct;
use Crehler\MojeBambinoEngine\Service\CrehlerContextService;
use Shopware\Core\Content\Product\ProductCollection;
use Shopware\Core\Content\Product\ProductEntity;
use Shopware\Core\Framework\Api\Context\AdminApiSource;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityLoadedEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntitySearchResultLoadedEvent;
use Shopware\Storefront\Page\Product\ProductPageCriteriaEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
use Shopware\Core\Content\Product\ProductEvents;
class ProductSubscriber implements EventSubscriberInterface
{
/**
* @var AdditionalArticlesService
*/
private $additionalArticlesService;
/**
* @var CrehlerContextService
*/
private $crehlerContextService;
/**
* ProductSubscriber constructor.
* @param AdditionalArticlesService $additionalArticlesService
* @param CrehlerContextService $crehlerContextService
*/
public function __construct(AdditionalArticlesService $additionalArticlesService, CrehlerContextService $crehlerContextService)
{
$this->additionalArticlesService = $additionalArticlesService;
$this->crehlerContextService = $crehlerContextService;
}
/**
* @return array
*/
public static function getSubscribedEvents(): array
{
return [
ProductPageLoadedEvent::class => 'onProductsLoaded',
ProductPageCriteriaEvent::class => 'onProductLoaderCriteria',
ProductEvents::PRODUCT_SEARCH_RESULT_LOADED_EVENT => 'onSearchResult',
ProductEvents::PRODUCT_LOADED_EVENT => 'onLoadResult'
];
}
/**
* @param ProductPageLoadedEvent $event
*/
public function onProductsLoaded(ProductPageLoadedEvent $event): void
{
if($this->crehlerContextService->get(CrehlerContextService::SITEMAP_GENERATE) || $this->crehlerContextService->get(CrehlerContextService::PRODUCT_EXPORT_GENERATE)) return;
$page = $event->getPage();
$product = $page->getProduct();
$context = $event->getSalesChannelContext();
/** @var ProductCollection $additionalArticles */
$additionalArticles = $this->additionalArticlesService->getPreparedAdditionalArticles($product, $context,$event->getRequest());
if(!$additionalArticles){
return;
};
$additionalArticlesDescription = $this->additionalArticlesService->getDescriptionAdditionalArticles($product, $context, $event->getRequest());
if ($additionalArticles->count() > 0) {
$additionalArticlesStruct = (new AdditionalArticleStruct())
->setProducts($additionalArticles)
->setDescription($additionalArticlesDescription);
$page->addExtension('additionalArticles', $additionalArticlesStruct);
}
}
/**
* @param ProductPageCriteriaEvent $event
*/
public function onProductLoaderCriteria(ProductPageCriteriaEvent $event)
{
if($this->crehlerContextService->get(CrehlerContextService::SITEMAP_GENERATE) || $this->crehlerContextService->get(CrehlerContextService::PRODUCT_EXPORT_GENERATE)) return;
try {
$event
->getCriteria()
->addAssociation('additionalProducts');
} catch (\Exception $e) {
}
}
/**
* @param EntityLoadedEvent $event
*/
public function onLoadResult(EntityLoadedEvent $event): void
{
if($this->crehlerContextService->get(CrehlerContextService::SITEMAP_GENERATE) || $this->crehlerContextService->get(CrehlerContextService::PRODUCT_EXPORT_GENERATE)) return;
if ($event->getContext()->getSource() instanceof AdminApiSource) {
/** @var ProductEntity $entity */
foreach ($event->getEntities() as $key => $entity) {
$extensions = $this->prepareExtensions($entity);
if (is_array($extensions)) {
$event->getEntities()[$key]->setExtensions($extensions);
}
}
}
}
/**
* @param EntitySearchResultLoadedEvent $event
*/
public function onSearchResult(EntitySearchResultLoadedEvent $event): void
{
if($this->crehlerContextService->get(CrehlerContextService::SITEMAP_GENERATE) || $this->crehlerContextService->get(CrehlerContextService::PRODUCT_EXPORT_GENERATE)) return;
if ($event->getContext()->getSource() instanceof AdminApiSource) {
/** @var ProductEntity $entity */
foreach ($event->getResult()->getEntities() as $key => $entity) {
$extensions = $this->prepareExtensions($entity);
if (is_array($extensions)) {
$event->getResult()->getEntities()->get($key)->setExtensions($extensions);
}
}
}
}
/**
* @param ProductEntity $entity
* @return array|null
*/
private function prepareExtensions(ProductEntity $entity): ?array
{
/** @var ProductCollection $additionalProductsExtension */
$additionalProductsExtension = $entity->getExtension('additionalProducts');
if ($additionalProductsExtension instanceof ProductCollection && count($additionalProductsExtension->getElements()) < 1) {
$product = $this->additionalArticlesService->loadAdditionalProducts($entity);
$extensions = $entity->getExtensions();
$extensions['additionalProducts'] = $product->getExtension('additionalProducts');
return $extensions;
}
return null;
}
}