<?php /** @noinspection PhpRedundantVariableDocTypeInspection */
/**
* LeopardSearchExtension
* Copyright (c) Die Leoparden GmbH
*/
namespace LeopardSearchExtension\Subscriber;
use Shopware\Core\Content\Product\Events\ProductListingCriteriaEvent;
use Shopware\Core\Content\Product\ProductEntity;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
/**
* Class AbstractSubscriber
*/
abstract class AbstractSubscriber implements EventSubscriberInterface
{
/**
* @var SystemConfigService
*/
private $systemConfigService;
/**
* @var EntityRepositoryInterface
*/
private $productRepository;
/**
* AbstractSubscriber constructor.
*
* @param SystemConfigService $systemConfigService
* @param EntityRepositoryInterface $productRepository
*/
public function __construct(SystemConfigService $systemConfigService, EntityRepositoryInterface $productRepository)
{
$this->systemConfigService = $systemConfigService;
$this->productRepository = $productRepository;
}
/**
* @param ProductListingCriteriaEvent $event
*/
public function onSearchCriteria(ProductListingCriteriaEvent $event): void
{
/** @var array $config */
$config = $this->getConfig($event->getSalesChannelContext());
/** @var string[] $searchTerm */
$filterTargets = $config['filterTargets'];
if (empty($config['activated']) || empty($filterTargets)) {
return;
}
/** @var Request $request */
$request = $event->getRequest();
/** @var string $searchTerm */
$searchTerm = trim($request->get('search'));
/** @var ProductEntity|null $productEntity */
$productEntity = $this->loadProductEntity($filterTargets, $searchTerm, $event->getContext());
$request->query->set('search', $productEntity ? $productEntity->getProductNumber() : $searchTerm);
if (!$productEntity instanceof ProductEntity) {
return;
}
$event->getCriteria()->addFilter(
new EqualsFilter(
'productNumber',
$productEntity->getProductNumber()
)
);
}
/**
* @return SystemConfigService
*/
protected function getSystemConfigService(): SystemConfigService
{
return $this->systemConfigService;
}
/**
* @param SalesChannelContext $salesChannelContext
*
* @return array
*/
protected function getConfig(SalesChannelContext $salesChannelContext): array
{
return $this->getSystemConfigService()->get('LeopardSearchExtension.config', $salesChannelContext->getSalesChannel()->getId());
}
/**
* @return EntityRepositoryInterface
*/
protected function getProductRepository(): EntityRepositoryInterface
{
return $this->productRepository;
}
/**
* @param array $filterFields
* @param string $filterValue
* @param Context $context
* @return ProductEntity|null
*/
protected function loadProductEntity(array $filterFields, string $filterValue, Context $context): ?ProductEntity
{
$entitySearchResult = $this->getProductRepository()->search(
(new Criteria())->addFilter(
array_reduce($filterFields, function (MultiFilter $multiFilter, string $field) use ($filterValue) {
return $multiFilter->addQuery(new EqualsFilter($field, $filterValue));
}, new MultiFilter(MultiFilter::CONNECTION_OR))),
$context
);
if ($entitySearchResult->count() === 1) {
return $entitySearchResult->first();
}
return null;
}
}