<?php declare(strict_types=1);
namespace cutvert\Seo\Subscriber;
use ECSPrefix20211002\Symfony\Component\HttpFoundation\Request;
use PhpParser\Node\Expr\BinaryOp\Equal;
use Shopware\Core\Content\Category\Tree\Tree;
use Shopware\Core\Content\Category\Tree\TreeItem;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityLoadedEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\AndFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\RangeFilter;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Shopware\Storefront\Event\StorefrontRenderEvent;
use Shopware\Storefront\Page\Navigation\NavigationPage;
use Shopware\Storefront\Page\Navigation\NavigationPageLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Shopware\Core\Content\Product\ProductEvents;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
class SeoSubscriber implements EventSubscriberInterface
{
/** @var SystemConfigService */
private $systemConfigService;
private EntityRepositoryInterface $faqRepository;
/**
* @var EntityRepositoryInterface
*/
private EntityRepositoryInterface $categoryRepo;
private EntityRepositoryInterface $productRepo;
public function __construct(SystemConfigService $systemConfigService,EntityRepositoryInterface $faqRepository,EntityRepositoryInterface $categoryRepo,EntityRepositoryInterface $productRepo)
{
$this->systemConfigService = $systemConfigService;
$this->faqRepository = $faqRepository;
$this->categoryRepo = $categoryRepo;
$this->productRepo = $productRepo;
}
public static function getSubscribedEvents(): array
{
return [
ProductEvents::PRODUCT_LOADED_EVENT => 'onProductsLoaded',
// NavigationPageLoadedEvent::class => "foobar",
StorefrontRenderEvent::class => 'onStorefrontRender'
];
}
public function onProductsLoaded(EntityLoadedEvent $event): void
{
$this->SeoSettings = $this->systemConfigService->get('cutvertSeo.config');
}
public function onStorefrontRender(StorefrontRenderEvent $event){
if (isset($event->getParameters()['page']) && property_exists($event->getParameters()['page'],'navigationId')){
$categoryId = $event->getParameters()['page']->getNavigationId();
/** @var $page NavigationPage */
$page = $event->getParameters()['page'];
$categoryTree = $page->getHeader()->getNavigation();
$categoryIds = $this->flatCategoryIds($categoryTree);
$criteria = new Criteria();
$criteria->addAssociation("seoUrls");
$criteria->setIds($categoryIds);
$searchResult = $this->categoryRepo->search($criteria, $event->getContext());
$categories = $searchResult->getEntities();
$cates = [];
/** @var Request $request */
$request = $event->getRequest();
$url = str_replace($request->getRequestUri(),'/',$request->getUri());
foreach ($categories as $key=>$category){
if (!empty($category->getSeoUrls()->first())) {
$cates[$category->getParentId()][] = [
"url" => $url . $category->getSeoUrls()->first()->getSeoPathInfo(),
"name" => $category->getName()
];
}
}
$event->setParameter('cutvertEventList',$event->getParameters()['page']);
$event->setParameter('cutvertNavigationId',$categoryId);
$event->setParameter('cutvertSeoConfig',$this->systemConfigService->get('cutvertSeo.config'));
if (isset($cates[$categoryId])){
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('category_id',$categoryId));
$faqs = $this->faqRepository->search($criteria,$event->getContext());
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('categoryTree',$categoryId));
$criteria->addAssociation("media");
$products = $this->productRepo->search($criteria,$event->getContext());
$productsInCategory = [];
$i = 1;
$productsInCategory['minPrice'] = '';
$productsInCategory['rating'] = 0;
$productsInCategory['ratingCount'] = 0;
$productMedias = [];
foreach ($products->getElements() as $product){
$rating = 0;
if ($product->getRatingAverage() != NULL) {
$rating = $product->getRatingAverage();
$productsInCategory['ratingCount'] = $i;
$i++;
}
if (count($productMedias) < 3){
if (isset(array_values($product->getMedia()->getElements())[0]))
$productMedias[] = array_values($product->getMedia()->getElements())[0]->getMedia()->getUrl();
}
$productsInCategory['rating'] = $productsInCategory['rating'] + $rating;
if ($productsInCategory['minPrice'] == '' ||array_values($product->getCheapestPrice()->getPrice()->getElements())[0]->getGross() < $productsInCategory['minPrice']) {
$productsInCategory['minPrice'] = array_values($product->getCheapestPrice()->getPrice()->getElements())[0]->getGross();
}
}
$productsInCategory['absoluteRating'] = 0;
if ($productsInCategory['ratingCount'] > 0) {
$productsInCategory['absoluteRating'] = $productsInCategory['rating'] / $productsInCategory['ratingCount'];
}
$event->setParameter('cutvertShopURL',$url);
$event->setParameter('cutvertFaqs',$faqs->getEntities()->getElements());
$event->setParameter('cutvertProductRepo',$productsInCategory);
$event->setParameter("cutvertSeoUrls", $cates[$categoryId]);
$event->setParameter('cutvertImages',$productMedias);
}
}
}
private function getRootCategory($categories, &$children = [], $currentId=''){
/**
* @var string $categoryId
* @var TreeItem $category
*/
foreach($categories as $categoryId => $category){
if(count($category->getChildren()) > 0){
if($category->getCategory()->getId() == $currentId){
$children[] = $category;
}
$this->getRootCategory($category->getChildren(), $children, $currentId);
}
}
return $children;
}
private function flatCategoryIds(Tree $categoryTree): array
{
$ids = [];
$this->flatCategoryIdArm($categoryTree->getTree(), $ids);
return $ids;
}
/**
* @param TreeItem[] $tree
* @param array $ids
*/
private function flatCategoryIdArm(array $tree, array &$ids)
{
foreach($tree as $item) {
$ids[] = $item->getCategory()->getId();
$this->flatCategoryIdArm($item->getChildren(), $ids);
}
}
}