<?php
namespace CoeWishlistSw6\Storefront\Seo;
use CoeWishlistSw6\Storefront\Seo\SeoUrlRoute\WishlistSeoUrlRoute;
use Shopware\Core\Content\Seo\SeoUrl\SeoUrlEntity;
use Shopware\Core\Content\Seo\SeoUrlUpdater;
use Shopware\Core\Defaults;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityDeletedEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\EntitySearchResult;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\ContainsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Class WishlistSeoSubscriber
* @package CoeWishlistSw6\Storefront\Seo
* @author Jeffry Block <jeffry.block@codeenterprise.de>
*/
Class WishlistSeoSubscriber implements EventSubscriberInterface{
/**
* @var SeoUrlUpdater
*/
private SeoUrlUpdater $seoUrlUpdater;
/**
* @var EntityRepository
*/
private EntityRepository $seoUrlRepository;
/**
* WishlistSeoSubscriber constructor.
* @param SeoUrlUpdater $seoUrlUpdater
* @param EntityRepository $seoUrlRepository
*/
public function __construct(SeoUrlUpdater $seoUrlUpdater, EntityRepository $seoUrlRepository) {
$this->seoUrlUpdater = $seoUrlUpdater;
$this->seoUrlRepository = $seoUrlRepository;
}
/**
* @return string[]
* @author Jeffry Block <jeffry.block@codeenterprise.de>
*/
public static function getSubscribedEvents(): array
{
return [
'coe_wishlist.written' => 'onEntityWritten',
'coe_wishlist.deleted' => 'onEntityDeleted'
];
}
/**
* @param EntityWrittenEvent $event
* @author Jeffry Block <jeffry.block@codeenterprise.de>
*/
public function onEntityWritten(EntityWrittenEvent $event): void
{
$this->seoUrlUpdater->update(WishlistSeoUrlRoute::ROUTE_NAME, $event->getIds());
$this->rewriteSeoUr($event->getContext());
}
/**
* @param EntityDeletedEvent $event
* @author Jeffry Block <jeffry.block@codeenterprise.de>
*/
public function onEntityDeleted(EntityDeletedEvent $event): void
{
$this->seoUrlUpdater->update(WishlistSeoUrlRoute::ROUTE_NAME, $event->getIds());
$this->rewriteSeoUr($event->getContext());
}
/**
* The SeoUpdater automatically saves the parameters in the pathInfo column as query (?a=1&b=2).
* But what we need is that the parameter is passed directly as a value as in the controller.
* Since there seems to be no configuration option for the SeoUpdater to do this, we simply do it ourselves with a simple search and replace.
* @param Context $context
* @author Jeffry Block <jeffry.block@codeenterprise.de>
*/
private function rewriteSeoUr(Context $context){
$criteria = new Criteria();
$criteria->addFilter(new MultiFilter(MultiFilter::CONNECTION_AND, [
new EqualsFilter('routeName', "frontend.wishlist.page"),
new ContainsFilter('pathInfo', "?"),
]));
/** @var EntitySearchResult $result */
$result = $this->seoUrlRepository->search($criteria, $context);
$updates = [];
/** @var SeoUrlEntity $seoUrlEntity */
foreach ($result->getEntities()->getIterator() as $seoUrlEntity) {
$updates[] = [
"id" => $seoUrlEntity->getId(),
"pathInfo" => str_replace("?wishlistId=","/", $seoUrlEntity->getPathInfo())
];
}
if (!empty($updates)) {
$this->seoUrlRepository->update($updates, $context);
}
}
}