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

SearchAction::__invoke()   B

Complexity

Conditions 6
Paths 3

Size

Total Lines 37
Code Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 23
nc 3
nop 1
dl 0
loc 37
rs 8.9297
c 1
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace BitBag\SyliusElasticsearchPlugin\Controller\Action\Shop;
6
7
use BitBag\SyliusElasticsearchPlugin\Block\SearchFormEventListener;
8
use BitBag\SyliusElasticsearchPlugin\Controller\RequestDataHandler\PaginationDataHandlerInterface;
9
use BitBag\SyliusElasticsearchPlugin\Facet\RegistryInterface;
10
use BitBag\SyliusElasticsearchPlugin\Model\Search;
11
use BitBag\SyliusElasticsearchPlugin\QueryBuilder\QueryBuilderInterface;
12
use Elastica\Query;
13
use FOS\ElasticaBundle\Finder\PaginatedFinderInterface;
14
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
15
use Symfony\Component\HttpFoundation\Request;
16
use Symfony\Component\HttpFoundation\Response;
17
18
final class SearchAction
19
{
20
    /** @var EngineInterface */
21
    private $templatingEngine;
22
23
    /** @var PaginatedFinderInterface */
24
    private $finder;
25
26
    /** @var SearchFormEventListener */
27
    private $searchFormEventListener;
28
29
    /** @var RegistryInterface */
30
    private $facetRegistry;
31
32
    /** @var QueryBuilderInterface */
33
    private $searchProductsQueryBuilder;
34
35
    /** @var PaginationDataHandlerInterface */
36
    private $paginationDataHandler;
37
38
    public function __construct(
39
        EngineInterface $templatingEngine,
40
        PaginatedFinderInterface $finder,
41
        SearchFormEventListener $searchFormEventListener,
42
        RegistryInterface $facetRegistry,
43
        QueryBuilderInterface $searchProductsQueryBuilder,
44
        PaginationDataHandlerInterface $paginationDataHandler
45
    ) {
46
        $this->templatingEngine = $templatingEngine;
47
        $this->finder = $finder;
48
        $this->searchFormEventListener = $searchFormEventListener;
49
        $this->facetRegistry = $facetRegistry;
50
        $this->searchProductsQueryBuilder = $searchProductsQueryBuilder;
51
        $this->paginationDataHandler = $paginationDataHandler;
52
    }
53
54
    public function __invoke(Request $request): Response
55
    {
56
        $template = $request->get('template');
57
        $form = $this->searchFormEventListener->getForm();
58
        $form->handleRequest($request);
59
60
        $results = null;
61
        if ($form->isSubmitted() && $form->isValid()) {
62
            /** @var Search $search */
63
            $search = $form->getData();
64
65
            $boolQuery = new Query\BoolQuery();
66
            $boolQuery->addMust(
67
                $this->searchProductsQueryBuilder->buildQuery(['query' => $search->getBox()->getQuery()])
68
            );
69
70
            if ($search->getFacets()) {
71
                foreach ($search->getFacets() as $facetId => $selectedBuckets) {
72
                    if (!$selectedBuckets) {
73
                        continue;
74
                    }
75
                    $facet = $this->facetRegistry->getFacetById($facetId);
76
                    $boolQuery->addFilter($facet->getQuery($selectedBuckets));
77
                }
78
            }
79
80
            $query = new Query($boolQuery);
81
82
            $results = $this->finder->findPaginated($query);
83
            $paginationData = $this->paginationDataHandler->retrieveData($request->query->all());
84
            $results->setCurrentPage($paginationData[PaginationDataHandlerInterface::PAGE_INDEX]);
85
            $results->setMaxPerPage($paginationData[PaginationDataHandlerInterface::LIMIT_INDEX]);
86
        }
87
88
        return $this->templatingEngine->renderResponse(
89
            $template,
90
            ['results' => $results, 'searchForm' => $form->createView()]
91
        );
92
    }
93
}
94