<?php declare(strict_types=1);
namespace MageWorx\SeoCrosslinks\Subscriber;
use MageWorx\SeoCrosslinks\Core\Content\Crosslink\Service\SalesChannelContextProvider;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityLoadedEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\NotFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Shopware\Core\Content\Category\CategoryEvents;
use Symfony\Component\HttpFoundation\RequestStack;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use MageWorx\SeoCrosslinks\Core\Content\Crosslink\Service\CrosslinkReplacer;
class CategorySubscriber implements EventSubscriberInterface
{
protected RequestStack $requestStack;
protected SystemConfigService $systemConfig;
protected EntityRepositoryInterface $crosslinkRepository;
protected CrosslinkReplacer $replacer;
protected SalesChannelContextProvider $salesChannelContextProvider;
protected $result;
public function __construct(
EntityRepositoryInterface $crosslinkRepository,
SystemConfigService $systemConfigService,
RequestStack $requestStack,
CrosslinkReplacer $replacer,
SalesChannelContextProvider $salesChannelContextProvider
) {
$this->crosslinkRepository = $crosslinkRepository;
$this->requestStack = $requestStack;
$this->systemConfig = $systemConfigService;
$this->replacer = $replacer;
$this->salesChannelContextProvider = $salesChannelContextProvider;
}
public static function getSubscribedEvents(): array
{
return [
CategoryEvents::CATEGORY_LOADED_EVENT => 'onCategoriesLoaded'
];
}
public function onCategoriesLoaded(EntityLoadedEvent $event)
{
if ($this->isAllow()) {
$id = $this->requestStack->getMainRequest()->attributes->get('navigationId');
$maxReplaceCount = $this->systemConfig->getInt('MageWorxSeoCrosslinks.config.categoryMaxReplacementCount');
if ($maxReplaceCount) {
$category = current($event->getEntities());
if ($category && $category->getId() === $id) {
$translated = $category->getTranslated();
if ($translated) {
if ($this->result === null && $translated['description']) {
$description = $translated['description'];
if ($description) {
$this->result = $this->getModifiedContent(
$description,
$category->getId(),
$event->getContext(),
$maxReplaceCount
);
}
}
if ($this->result) {
$translated['description'] = $this->result;
$category->setTranslated($translated);
$category->setDescription($translated['description']);
}
}
}
}
}
}
protected function isAllow(): bool
{
if ($this->systemConfig->getBool('MageWorxSeoCrosslinks.config.enable')) {
$request = $this->requestStack->getMainRequest();
if ($request) {
$route = $request->attributes->get('_route');
$categoryId = $request->attributes->get('navigationId');
if ($route === 'frontend.navigation.page' && $categoryId) {
return true;
}
}
}
return false;
}
/**
* @param string $content
* @param string $entityId
* @param Context $context
* @param int $maxCount
* @return false|string
*/
protected function getModifiedContent(
string $content,
string $entityId,
Context $context,
int $maxCount
) {
$criteria = new Criteria();
$criteria->addFilter(
new EqualsFilter('isActive', true),
new EqualsFilter('inCategory', true),
new EqualsFilter('languageId', $context->getLanguageId()),
new EqualsFilter(
'salesChannels.salesChannelId',
$this->salesChannelContextProvider->getSalesChannelContext($context)->getSalesChannelId()
),
new NotFilter('AND', [
new EqualsFilter('internalLink', $entityId)
]),
);
$criteria->addSorting(new FieldSorting('priority', 'DESC'));
$crosslinkCollection = $this->crosslinkRepository->search($criteria, $context)->getEntities();
return $this->replacer->replace($context, $crosslinkCollection, $content, $maxCount);
}
}