<?php declare(strict_types=1);
namespace FourtwosixCategoryDescriptionOnPDP\Subscriber;
use Shopware\Core\Content\Category\CategoryEntity;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\EntitySearchResult;
use Shopware\Core\Framework\Struct\ArrayStruct;
use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class AddCategoryDescription2PDPSubscriber implements EventSubscriberInterface
{
protected EntityRepositoryInterface $categoryRepository;
/**
* @param EntityRepositoryInterface $categoryRepository
*/
public function __construct(
EntityRepositoryInterface $categoryRepository
) {
$this->categoryRepository = $categoryRepository;
}
/**
* @return string[]
*/
public static function getSubscribedEvents(): array
{
return [
ProductPageLoadedEvent::class => 'onProductsLoaded',
];
}
/**
* @param ProductPageLoadedEvent $event
* @return void
*/
public function onProductsLoaded(ProductPageLoadedEvent $event): void
{
$context = $event->getContext();
$nonSeoCategoryIds = $event->getPage()->getProduct()->getCategoryIds();
$seoCategory = $event->getPage()->getProduct()->getSeoCategory();
// If not found there is something wrong skip to avoid errors, no extension will be set
if (is_null($seoCategory) || is_null($nonSeoCategoryIds)) {
return;
}
$seoCategoryPath = $seoCategory->getPath()."|".$seoCategory->getId();
$seoCategoryIds = array_reverse(array_filter(explode("|", $seoCategoryPath)));
// Remove seo category from nonSeoCategory to avoid duplicate values
$seoCategoryIndex = array_search($seoCategory->getId(), $nonSeoCategoryIds);
unset($nonSeoCategoryIds[$seoCategoryIndex]);
// Get sorted categories id from non seo categories using path if more than one category assigned to product
if ($nonSeoCategoryIds) {
$nonSeoCategoryEntities = $this->getEntities($nonSeoCategoryIds, $context);
$sortedNonSeoCategoriesId = $this->sortCategoriesWithPath($nonSeoCategoryEntities);
$sortedCategories = array_merge($seoCategoryIds, $sortedNonSeoCategoriesId);
} else {
// Avoid loading all categories if nonSeoCategoryIds is empty
$sortedCategories = $seoCategoryIds;
}
// We want seoCategoryIds to be processed first
$allCategoriesFromPath = $this->getEntities($sortedCategories, $context);
/** @var CategoryEntity $categoryFromPath */
foreach ($allCategoriesFromPath->getEntities() as $categoryFromPath) {
$description = $categoryFromPath->getTranslated()["description"] ?? null;
if (!is_null($description) && $description !== '') {
$event->getPage()->addExtension(
"FourtwosixCategoryDescriptionPLP",
new ArrayStruct([$description])
);
return;
}
}
}
/**
* @param array $categoryIds
* @param Context $context
* @return EntitySearchResult
*/
protected function getEntities(array $categoryIds, Context $context): EntitySearchResult
{
$criteria = new Criteria($categoryIds);
return $this->categoryRepository->search($criteria, $context);
}
/**
* @param EntitySearchResult $nonSeoCategoryEntities
* @return array
*/
protected function sortCategoriesWithPath(EntitySearchResult $nonSeoCategoryEntities): array
{
$orderedCategories = [];
/** @var CategoryEntity $entity */
foreach ($nonSeoCategoryEntities->getEntities() as $entity) {
// Current Category is not present in path
$entityPath = $entity->getPath()."|{$entity->id}";
$path = array_filter(explode("|", $entityPath));
$orderedCategories = [...$orderedCategories, ...$path];
}
return $orderedCategories;
}
}