Passed
Push — master ( cc4e78...1262d4 )
by Damian
04:08
created

SearchType::buildForm()   A

Complexity

Conditions 5
Paths 1

Size

Total Lines 38
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 22
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 38
rs 9.2568
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BitBag\SyliusElasticsearchPlugin\Form\Type;
6
7
use BitBag\SyliusElasticsearchPlugin\Facet\RegistryInterface;
8
use BitBag\SyliusElasticsearchPlugin\Model\Search;
9
use BitBag\SyliusElasticsearchPlugin\Model\SearchBox;
10
use BitBag\SyliusElasticsearchPlugin\QueryBuilder\QueryBuilderInterface;
11
use Elastica\Query;
12
use FOS\ElasticaBundle\Finder\PaginatedFinderInterface;
13
use FOS\ElasticaBundle\Paginator\FantaPaginatorAdapter;
14
use Pagerfanta\Adapter\AdapterInterface;
15
use Symfony\Component\Form\AbstractType;
16
use Symfony\Component\Form\FormBuilderInterface;
17
use Symfony\Component\Form\FormEvent;
18
use Symfony\Component\Form\FormEvents;
19
use Symfony\Component\Form\FormInterface;
20
use Symfony\Component\OptionsResolver\OptionsResolver;
21
22
final class SearchType extends AbstractType
23
{
24
    /** @var PaginatedFinderInterface */
25
    private $finder;
26
27
    /** @var RegistryInterface */
28
    private $facetRegistry;
29
30
    /** @var QueryBuilderInterface */
31
    private $searchProductsQueryBuilder;
32
33
    public function __construct(
34
        PaginatedFinderInterface $finder,
35
        RegistryInterface $facetRegistry,
36
        QueryBuilderInterface $searchProductsQueryBuilder
37
    ) {
38
        $this->finder = $finder;
39
        $this->facetRegistry = $facetRegistry;
40
        $this->searchProductsQueryBuilder = $searchProductsQueryBuilder;
41
    }
42
43
    public function buildForm(FormBuilderInterface $builder, array $options): void
44
    {
45
        $builder
46
            ->add('box', SearchBoxType::class, ['label' => false])
47
            ->setMethod('GET')
48
        ;
49
50
        $formModifier = function (FormInterface $form, AdapterInterface $adapter) {
51
            if (!$adapter instanceof FantaPaginatorAdapter) {
52
                return;
53
            }
54
55
            $form->add('facets', SearchFacetsType::class, ['facets' => $adapter->getAggregations(), 'label' => false]);
56
        };
57
58
        $builder
59
            ->get('box')
60
            ->addEventListener(
61
                FormEvents::POST_SUBMIT,
62
                function (FormEvent $event) use ($formModifier) {
63
                    /** @var SearchBox $data */
64
                    $data = $event->getForm()->getData();
65
66
                    if (!$data->getQuery()) {
67
                        return;
68
                    }
69
70
                    $query = new Query($this->searchProductsQueryBuilder->buildQuery(['query' => $data->getQuery()]));
71
72
                    foreach ($this->facetRegistry->getFacets() as $facetId => $facet) {
73
                        $query->addAggregation($facet->getAggregation()->setName($facetId));
74
                    }
75
                    $query->setSize(0);
76
77
                    $results = $this->finder->findPaginated($query);
78
79
                    if ($results->getAdapter()) {
80
                        $formModifier($event->getForm()->getParent(), $results->getAdapter());
81
                    }
82
                }
83
            )
84
        ;
85
    }
86
87
    public function configureOptions(OptionsResolver $resolver): void
88
    {
89
        $resolver->setDefaults([
90
            'data_class' => Search::class,
91
            'csrf_protection' => false
92
        ]);
93
    }
94
95
    public function getBlockPrefix(): string
96
    {
97
        return 'bitbag_elasticsearch_search';
98
    }
99
}
100