mirror of
https://github.com/jbcr/SyliusElasticsearchPlugin.git
synced 2026-03-24 00:42:08 +01:00
OP-7: Add facets to search form
This commit is contained in:
@@ -10,16 +10,48 @@ declare(strict_types=1);
|
||||
|
||||
namespace BitBag\SyliusElasticsearchPlugin\Form\Type;
|
||||
|
||||
use BitBag\SyliusElasticsearchPlugin\Controller\RequestDataHandler\DataHandlerInterface;
|
||||
use BitBag\SyliusElasticsearchPlugin\Facet\RegistryInterface;
|
||||
use BitBag\SyliusElasticsearchPlugin\QueryBuilder\QueryBuilderInterface;
|
||||
use FOS\ElasticaBundle\Finder\PaginatedFinderInterface;
|
||||
use Symfony\Component\Form\FormBuilderInterface;
|
||||
use Symfony\Component\Form\FormEvent;
|
||||
use Symfony\Component\Form\FormEvents;
|
||||
use Symfony\Component\Form\FormInterface;
|
||||
use Pagerfanta\Adapter\AdapterInterface;
|
||||
use FOS\ElasticaBundle\Paginator\FantaPaginatorAdapter;
|
||||
use Elastica\Query;
|
||||
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||
|
||||
final class ShopProductsFilterType extends AbstractFilterType
|
||||
{
|
||||
/** @var string */
|
||||
private $namePropertyPrefix;
|
||||
|
||||
public function __construct(string $namePropertyPrefix)
|
||||
{
|
||||
/** @var PaginatedFinderInterface */
|
||||
private $finder;
|
||||
|
||||
/** @var RegistryInterface */
|
||||
private $facetRegistry;
|
||||
|
||||
/** @var QueryBuilderInterface */
|
||||
private $searchProductsQueryBuilder;
|
||||
|
||||
/** @var DataHandlerInterface */
|
||||
private $shopProductListDataHandler;
|
||||
|
||||
public function __construct(
|
||||
string $namePropertyPrefix,
|
||||
PaginatedFinderInterface $finder,
|
||||
RegistryInterface $facetRegistry,
|
||||
QueryBuilderInterface $searchProductsQueryBuilder,
|
||||
DataHandlerInterface $shopProductListDataHandler
|
||||
) {
|
||||
$this->namePropertyPrefix = $namePropertyPrefix;
|
||||
$this->finder = $finder;
|
||||
$this->facetRegistry = $facetRegistry;
|
||||
$this->searchProductsQueryBuilder = $searchProductsQueryBuilder;
|
||||
$this->shopProductListDataHandler = $shopProductListDataHandler;
|
||||
}
|
||||
|
||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||
@@ -29,6 +61,57 @@ final class ShopProductsFilterType extends AbstractFilterType
|
||||
->add('options', ProductOptionsFilterType::class, ['required' => false, 'label' => false])
|
||||
->add('attributes', ProductAttributesFilterType::class, ['required' => false, 'label' => false])
|
||||
->add('price', PriceFilterType::class, ['required' => false, 'label' => false])
|
||||
;
|
||||
->setMethod('GET');
|
||||
|
||||
$builder->addEventListener(FormEvents::PRE_SUBMIT, [$this, 'resolveFacets']);
|
||||
}
|
||||
|
||||
public function configureOptions(OptionsResolver $resolver): void
|
||||
{
|
||||
$resolver->setDefaults([
|
||||
'csrf_protection' => false,
|
||||
]);
|
||||
}
|
||||
|
||||
public function resolveFacets(FormEvent $event): void
|
||||
{
|
||||
$query = $this->getQuery($event);
|
||||
|
||||
foreach ($this->facetRegistry->getFacets() as $facetId => $facet) {
|
||||
$query->addAggregation($facet->getAggregation()->setName($facetId));
|
||||
}
|
||||
|
||||
$query->setSize(0);
|
||||
|
||||
$results = $this->finder->findPaginated($query);
|
||||
|
||||
if ($results->getAdapter()) {
|
||||
$this->modifyForm($event->getForm(), $results->getAdapter());
|
||||
}
|
||||
}
|
||||
|
||||
private function getQuery(FormEvent $event): Query
|
||||
{
|
||||
$eventData = $event->getData();
|
||||
if (!isset($eventData[$this->namePropertyPrefix])) {
|
||||
$eventData[$this->namePropertyPrefix] = '';
|
||||
}
|
||||
|
||||
$data = $this->shopProductListDataHandler->retrieveData($eventData);
|
||||
|
||||
return new Query($this->searchProductsQueryBuilder->buildQuery($data));
|
||||
}
|
||||
|
||||
private function modifyForm(FormInterface $form, AdapterInterface $adapter): void
|
||||
{
|
||||
if (!$adapter instanceof FantaPaginatorAdapter) {
|
||||
return;
|
||||
}
|
||||
|
||||
$form->add('facets', SearchFacetsType::class, [
|
||||
'facets' => $adapter->getAggregations(),
|
||||
'label' => false
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,10 @@
|
||||
|
||||
<service id="bitbag_sylius_elasticsearch_plugin.form.type.shop_products_filter" class="BitBag\SyliusElasticsearchPlugin\Form\Type\ShopProductsFilterType">
|
||||
<argument>%bitbag_es_shop_name_property_prefix%</argument>
|
||||
<argument type="service" id="fos_elastica.finder.bitbag_shop_product" />
|
||||
<argument type="service" id="bitbag_sylius_elasticsearch_plugin.facet.taxon_registry" />
|
||||
<argument type="service" id="bitbag_sylius_elasticsearch_plugin.query_builder.shop_products" />
|
||||
<argument type="service" id="bitbag_sylius_elasticsearch_plugin.controller.request_data_handler.shop_product_list" />
|
||||
<tag name="form.type" />
|
||||
</service>
|
||||
|
||||
|
||||
@@ -7,6 +7,9 @@
|
||||
<div class="item">
|
||||
{{ form_row(form.price) }}
|
||||
</div>
|
||||
<div class="item">
|
||||
{{ form_row(form.facets) }}
|
||||
</div>
|
||||
<div class="item">
|
||||
<button type="submit" class="ui primary icon labeled button" style="width: 100%;"><i class="search icon"></i> {{ 'bitbag_sylius_elasticsearch_plugin.ui.filter'|trans }}</button>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user