<?php
declare(strict_types=1);
namespace BitBag\OpenMarketplace\Component\Elasticsearch\Form\Type;
use BitBag\OpenMarketplace\Component\Elasticsearch\DependencyInjection\RegisterProductAttributesFacetsInterface;
use BitBag\SyliusElasticsearchPlugin\Facet\RegistryInterface;
use BitBag\SyliusElasticsearchPlugin\Form\Type\SearchBoxType;
use BitBag\SyliusElasticsearchPlugin\Form\Type\SearchFacetsType;
use BitBag\SyliusElasticsearchPlugin\Model\Search;
use BitBag\SyliusElasticsearchPlugin\Model\SearchBox;
use BitBag\SyliusElasticsearchPlugin\QueryBuilder\QueryBuilderInterface;
use Elastica\Query;
use FOS\ElasticaBundle\Finder\PaginatedFinderInterface;
use FOS\ElasticaBundle\Paginator\FantaPaginatorAdapter;
use Pagerfanta\Adapter\AdapterInterface;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
final class SearchType extends AbstractType
{
public function __construct(
private PaginatedFinderInterface $finder,
private RegistryInterface $facetRegistry,
private QueryBuilderInterface $searchProductsQueryBuilder,
private RegisterProductAttributesFacetsInterface $facetRegistrator
) {
}
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('box', SearchBoxType::class, ['label' => false])
->setMethod('GET')
;
$formModifier = function (FormInterface $form, AdapterInterface $adapter) {
if (!$adapter instanceof FantaPaginatorAdapter) {
return;
}
$form->add('filters', SearchFacetsType::class, [
'facets' => $adapter->getAggregations(),
'label' => false,
'property_path' => 'facets',
]);
};
$builder
->get('box')
->addEventListener(
FormEvents::POST_SUBMIT,
function (FormEvent $event) use ($formModifier) {
/** @var SearchBox $data */
$data = $event->getForm()->getData();
if (!$data->getQuery()) {
return;
}
$query = new Query($this->searchProductsQueryBuilder->buildQuery(['query' => $data->getQuery()]));
$this->facetRegistrator->registerFacetsForWideSearch();
//$this->facetRegistrator->registerFacetsForTaxonSearch();
foreach ($this->facetRegistry->getFacets() as $facetId => $facet) {
$query->addAggregation($facet->getAggregation()->setName($facetId));
}
$query->setSize(0);
$results = $this->finder->findPaginated($query);
if (null !== $event->getForm()->getParent()) {
$formModifier($event->getForm()->getParent(), $results->getAdapter());
}
}
)
;
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => Search::class,
'csrf_protection' => false,
]);
}
public function getBlockPrefix(): string
{
return 'parameters';
}
}