<?php
declare(strict_types=1);
namespace App\Controller\Shop;
use App\Assigner\NoResultSearchAssigner;
use App\Entity\Statistics\NoResultSearch;
use App\Repository\Statistics\NoResultSearchRepository;
use App\Service\SpecialCharactersService;
use Doctrine\ORM\EntityManagerInterface;
use MonsieurBiz\SyliusSearchPlugin\Exception\UnknownRequestTypeException;
use MonsieurBiz\SyliusSearchPlugin\Model\Documentable\DocumentableInterface;
use MonsieurBiz\SyliusSearchPlugin\Search\Request\RequestConfiguration;
use MonsieurBiz\SyliusSearchPlugin\Search\Request\RequestInterface;
use MonsieurBiz\SyliusSearchPlugin\Search\Search;
use MonsieurBiz\SyliusSettingsPlugin\Settings\SettingsInterface;
use Sylius\Bundle\ResourceBundle\Controller\Parameters;
use Sylius\Bundle\ResourceBundle\Controller\ParametersParserInterface;
use Sylius\Component\Channel\Context\ChannelContextInterface;
use Sylius\Component\Currency\Context\CurrencyContextInterface;
use Sylius\Component\Locale\Context\LocaleContextInterface;
use Sylius\Component\Registry\ServiceRegistryInterface;
use Sylius\Component\Taxonomy\Repository\TaxonRepositoryInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Intl\Currencies;
class SearchController extends AbstractController
{
private TaxonRepositoryInterface $taxonRepository;
private Search $search;
private CurrencyContextInterface $currencyContext;
private LocaleContextInterface $localeContext;
private ChannelContextInterface $channelContext;
private SettingsInterface $searchSettings;
private ServiceRegistryInterface $documentableRegistry;
private ParametersParserInterface $parametersParser;
private NoResultSearchAssigner $noResultSearchAssigner;
private NoResultSearchRepository $noResultSearchRepository;
private SpecialCharactersService $specialCharactersService;
private EntityManagerInterface $entityManager;
public function __construct(
TaxonRepositoryInterface $taxonRepository,
Search $search,
CurrencyContextInterface $currencyContext,
LocaleContextInterface $localeContext,
ChannelContextInterface $channelContext,
SettingsInterface $searchSettings,
ServiceRegistryInterface $documentableRegistry,
ParametersParserInterface $parametersParser,
NoResultSearchAssigner $noResultSearchAssigner,
NoResultSearchRepository $noResultSearchRepository,
SpecialCharactersService $specialCharactersService,
EntityManagerInterface $entityManager
) {
$this->taxonRepository = $taxonRepository;
$this->search = $search;
$this->currencyContext = $currencyContext;
$this->localeContext = $localeContext;
$this->channelContext = $channelContext;
$this->searchSettings = $searchSettings;
$this->documentableRegistry = $documentableRegistry;
$this->parametersParser = $parametersParser;
$this->noResultSearchAssigner = $noResultSearchAssigner;
$this->noResultSearchRepository = $noResultSearchRepository;
$this->specialCharactersService = $specialCharactersService;
$this->entityManager = $entityManager;
}
// TODO add an optional parameter $documentType (nullable => get the default document type)
public function searchAction(Request $request, string $query): Response
{
/** @var DocumentableInterface $documentable */
$documentable = $this->documentableRegistry->get('search.documentable.monsieurbiz_product');
$requestConfiguration = new RequestConfiguration(
$request,
RequestInterface::SEARCH_TYPE,
$documentable,
$this->searchSettings,
$this->channelContext
);
$result = $this->search->search($requestConfiguration);
if (count($result) === 0) {
$this->noResultSearchAssigner->assign(urldecode($query));
// relancer la recherche avec une query associée si elle existe
/** @var NoResultSearch $noResultSearch */
$noResultSearch = $this->noResultSearchRepository->findOneBy(['search' => trim($this->specialCharactersService->replaceAccentedCharacters(urldecode($query)))]);
if ($noResultSearch && $noResultSearch->getAssociatedWord()) {
return $this->redirectToRoute('monsieurbiz_search_search', ['query' => $noResultSearch->getAssociatedWord()]);
}
} else {
//rechercher si une noresultsearch existe et la supprimer car il y a maintenant des résultats
/** @var NoResultSearch $noResultSearch */
$noResultSearch = $this->noResultSearchRepository->findOneBy(['search' => trim($this->specialCharactersService->replaceAccentedCharacters(urldecode($query)))]);
if ($noResultSearch) {
$this->entityManager->remove($noResultSearch);
$this->entityManager->flush();
}
}
return $this->render('@MonsieurBizSyliusSearchPlugin/Search/result.html.twig', [
'documentable' => $result->getDocumentable(),
'requestConfiguration' => $requestConfiguration,
'query' => urldecode($query),
'query_url' => $query,
'result' => $result,
'currencySymbol' => Currencies::getSymbol($this->currencyContext->getCurrencyCode(), $this->localeContext->getLocaleCode()),
]);
}
/**
* Post search.
*/
public function postAction(Request $request): RedirectResponse
{
$query = (array) $request->request->get('monsieurbiz_searchplugin_search') ?? [];
$query = $query['query'] ?? '';
return $this->redirect(
$this->generateUrl(
'monsieurbiz_search_search',
['query' => urlencode($query)]
)
);
}
/**
* Perform the instant search action & display results.
*/
public function instantAction(Request $request): Response
{
$results = [];
/** @var DocumentableInterface $documentable */
foreach ($this->documentableRegistry->all() as $documentable) {
if (!(bool) $this->searchSettings->getCurrentValue($this->channelContext->getChannel(), null, 'instant_search_enabled__' . $documentable->getIndexCode())) {
continue;
}
$requestConfiguration = new RequestConfiguration(
$request,
RequestInterface::INSTANT_TYPE,
$documentable,
$this->searchSettings,
$this->channelContext,
new Parameters($this->parametersParser->parseRequestValues($request->attributes->get('_sylius', []), $request))
);
try {
$results[] = $this->search->search($requestConfiguration);
} catch (UnknownRequestTypeException $e) {
continue;
}
}
return $this->render('@MonsieurBizSyliusSearchPlugin/Instant/result.html.twig', [
'results' => $results,
'currencySymbol' => Currencies::getSymbol($this->currencyContext->getCurrencyCode(), $this->localeContext->getLocaleCode()),
]);
}
public function taxonAction(Request $request): Response
{
/** @var DocumentableInterface $documentable */
$documentable = $this->documentableRegistry->get('search.documentable.monsieurbiz_product');
$requestConfiguration = new RequestConfiguration(
$request,
RequestInterface::TAXON_TYPE,
$documentable,
$this->searchSettings,
$this->channelContext,
new Parameters($this->parametersParser->parseRequestValues($request->attributes->get('_sylius', []), $request))
);
$result = $this->search->search($requestConfiguration);
$taxon = $this->taxonRepository->findOneBySlug(
$request->get('slug'),
$this->localeContext->getLocaleCode()
);
return $this->render('@MonsieurBizSyliusSearchPlugin/Taxon/result.html.twig', [
'taxon' => $taxon,
'requestConfiguration' => $requestConfiguration,
'result' => $result,
'currencySymbol' => Currencies::getSymbol($this->currencyContext->getCurrencyCode(), $this->localeContext->getLocaleCode()),
]);
}
}