<?php declare(strict_types=1);
namespace Uandi\EFB\Storefront\Subscriber;
use Shopware\Core\Content\Product\Aggregate\ProductMedia\ProductMediaCollection;
use Shopware\Core\Content\Product\Aggregate\ProductMedia\ProductMediaEntity;
use Shopware\Core\Content\Product\ProductEntity;
use Shopware\Core\Content\Product\SalesChannel\ProductAvailableFilter;
use Shopware\Core\Content\Product\SalesChannel\SalesChannelProductEntity;
use Shopware\Core\Content\Property\Aggregate\PropertyGroupOption\PropertyGroupOptionEntity;
use Shopware\Core\Content\Property\PropertyGroupCollection;
use Shopware\Core\Content\Property\PropertyGroupEntity;
use Shopware\Core\Framework\DataAbstractionLayer\EntityCollection;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\EntitySearchResult;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\OrFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
use Shopware\Core\Framework\Struct\Struct;
use Shopware\Core\System\SalesChannel\Entity\SalesChannelRepository;
use Shopware\Core\System\SalesChannel\Entity\SalesChannelRepositoryInterface;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Storefront\Page\Product\ProductPageCriteriaEvent;
use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
use Shopware\Storefront\Pagelet\Header\HeaderPageletLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Uandi\EFB\Storefront\Service\VariantLoader;
use Uandi\EFB\Storefront\Struct\ProductVariantTableStruct;
class ProductDetailSubscriber implements EventSubscriberInterface
{
const BADGE_TAG_NAME = 'badge';
protected SalesChannelRepositoryInterface $productRepository;
protected VariantLoader $variantLoader;
public static function getSubscribedEvents(): array
{
return [
ProductPageLoadedEvent::class => 'onProductPageLoaded',
ProductPageCriteriaEvent::class => 'extendProductPageCriteria'
];
}
public function __construct(SalesChannelRepositoryInterface $repository, VariantLoader $variantLoader)
{
$this->productRepository = $repository;
$this->variantLoader = $variantLoader;
}
public function extendProductPageCriteria(ProductPageCriteriaEvent $event)
{
$event->getCriteria()->addAssociation('media.media.tags');
}
public function onProductPageLoaded(ProductPageLoadedEvent $event)
{
$product = $event->getPage()->getProduct();
$context = $event->getSalesChannelContext();
$this->loadParent($product, $context);
$this->filterBadges($product);
$this->variantLoader->loadVariantTable($product, $context);
}
private function loadParent(ProductEntity $product, SalesChannelContext $context): void
{
if ($product->getParentId()) {
$parent = $this->productRepository->search(new Criteria([$product->getParentId()]), $context)->first();
if ($parent !== null) {
$product->setParent($parent);
}
}
}
private function filterBadges(ProductEntity $product): void
{
$mediaCollection = $product->getMedia();
$badges = $mediaCollection->filter(static function(ProductMediaEntity $media) {
$tags = $media->getMedia()->getTags();
return $tags && $tags->filterByProperty('name', static::BADGE_TAG_NAME)->count();
});
foreach ($badges->getIds() as $mediaId) {
$mediaCollection->remove($mediaId);
}
$product->addExtension('badges', $badges);
}
}