<?php declare(strict_types=1);
namespace NrbnSenertec\Subscriber;
use Shopware\Core\Content\Product\Events\ProductSearchCriteriaEvent;
use Shopware\Core\Content\Product\Events\ProductSuggestCriteriaEvent;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Query\ScoreQuery;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class SearchSubscriber implements EventSubscriberInterface{
/**
* @var EntityRepository
*/
protected EntityRepository $nrbnSearchKeywordRepository;
public function __construct(
EntityRepository $nrbnSearchKeywordRepository
){
$this->nrbnSearchKeywordRepository = $nrbnSearchKeywordRepository;
}
public static function getSubscribedEvents(): array {
return [
ProductSearchCriteriaEvent::class => 'searchCriteria',
ProductSuggestCriteriaEvent::class => 'suggestCriteria'
];
}
public function searchCriteria(ProductSearchCriteriaEvent $event) {
if(!$event->getSalesChannelContext()->getCustomer()){
$event->getCriteria()->setLimit(0);
return;
}
if(!$event->getRequest()->query->get("advanced")){
return;
}
return $this->createAdvancedCriteria($event);
}
public function suggestCriteria(ProductSuggestCriteriaEvent $event) {
if(!$event->getSalesChannelContext()->getCustomer()){
$event->getCriteria()->setLimit(0);
return;
}
if(!$event->getRequest()->query->get("advanced")){
return;
}
return $this->createAdvancedCriteria($event);
}
/**
* @param $event
* @return mixed
*/
private function createAdvancedCriteria($event)
{
$criteria = $event->getCriteria();
$productFilters = $criteria->getFilters()[0];
$searchKeywordFilters = $criteria->getFilters()[1];
$queries = $criteria->getQueries();
$criteria->resetFilters();
$criteria->addFilter($productFilters);
foreach ($searchKeywordFilters->getQueries() as $filter){
$values = $filter->getValue();
$field = str_replace("searchKeywords", "nrbnSearchKeywords", $filter->getField());
$newFilter = null;
if($filter instanceof EqualsAnyFilter){
$newFilter = new EqualsAnyFilter($field, $values);
} elseif ($filter instanceof EqualsFilter) {
$newFilter = new EqualsFilter($field, $values);
}
if($newFilter){
$criteria->addFilter($newFilter);
}
}
$criteria->resetQueries();
foreach ($queries as $query){
$scoreField = "product.nrbnSearchKeywords.ranking";
$value = $query->getQuery()->getValue();
$field = str_replace("searchKeywords", "nrbnSearchKeywords", $query->getQuery()->getField());
$filter = new EqualsFilter($field, $value);
$newScoreQuery = new ScoreQuery($filter, $query->getScore(), $scoreField);
$criteria->addQuery($newScoreQuery);
}
return $event;
}
}