Passed
Push — master ( 2529fd...42b327 )
by Matt
02:50 queued 13s
created

SearchController::index()   B

Complexity

Conditions 3
Paths 2

Size

Total Lines 95
Code Lines 57

Duplication

Lines 0
Ratio 0 %

Importance

Changes 5
Bugs 0 Features 0
Metric Value
cc 3
eloc 57
c 5
b 0
f 0
nc 2
nop 3
dl 0
loc 95
rs 8.9381

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace App\Controller\Search;
4
5
use App\Entity\Image;
6
use Elastica\Collapse\InnerHits as CollapseInnerHits;
7
use Elastica\Query;
8
use Elastica\Query\BoolQuery;
9
use Elastica\Query\InnerHits;
10
use Elastica\Query\MatchQuery;
11
use Elastica\Query\MultiMatch;
12
use Elastica\Query\Nested;
13
use Elastica\Query\QueryString;
14
use FOS\ElasticaBundle\Finder\FinderInterface;
15
use FOS\ElasticaBundle\Finder\PaginatedFinderInterface;
16
use Knp\Component\Pager\PaginatorInterface;
17
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
18
use Symfony\Component\Form\Extension\Core\Type\SearchType;
19
use Symfony\Component\HttpFoundation\Request;
20
use Symfony\Component\HttpFoundation\Response;
21
use Symfony\Component\Routing\Annotation\Route;
22
23
/**
24
 * @Route("/search", name="search_")
25
 *
26
 */
27
class SearchController extends AbstractController
28
{
29
    /**
30
     * @Route("/", name="index", methods={"GET", "POST"})
31
     */
32
    public function index(
33
        Request $request,
34
        //PaginatedFinderInterface $imageFinder,
35
        PaginatedFinderInterface $wanderFinder,
36
        PaginatorInterface $paginator): Response
37
    {
38
        // $finder = $this->container->get('fos_elastica.finder.app');
39
40
        // TODO: Maybe try combining results from $imageFinder and $wanderFinder?
41
42
        $form = $this->createFormBuilder(null, ['method' => 'GET' ])
43
            ->add('query', SearchType::class, ['label' => false])
44
            ->getForm();
45
46
        $form->handleRequest($request);
47
        $pagination = null;
48
        if ($form->isSubmitted() && $form->isValid()) {
49
            $data = $form->getData();
50
51
            // Nested query to find all wanders with images that match
52
            // the text.
53
            $nmm = new MultiMatch();
54
            $nmm->setQuery($data['query']);
55
            // TODO By the looks of https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-multi-match-query.html
56
            // you might be able to just not setFields and it'll default to * and might catch everything
57
            // anyway.
58
            $nmm->setFields(['images.title', 'images.description', 'images.tags', 'images.auto_tags']);
59
60
            $nested = new Nested();
61
            $nested->setPath('images');
62
            $nested->setQuery($nmm);
63
64
            $innerHits = new InnerHits();
65
            $innerHits->setHighlight(['fields' => [
66
                'images.title' => [
67
                    'number_of_fragments' => 0,
68
                    'no_match_size' => 1024,
69
                    'pre_tags' => ['<mark>'],
70
                    'post_tags' => ['</mark>']
71
                ],
72
                'images.description' => [
73
                    'no_match_size' => 1024,
74
                    'pre_tags' => ['<mark>'],
75
                    'post_tags' => ['</mark>']
76
                ],
77
                'images.tags' => [
78
                    'pre_tags' => ['<mark>'],
79
                    'post_tags' => ['</mark>']
80
                ],
81
                'images.auto_tags' => [
82
                    'pre_tags' => ['<mark>'],
83
                    'post_tags' => ['</mark>']
84
                ]
85
            ]]);
86
            $nested->setInnerHits($innerHits);
87
88
            // Combine that with a normal query to find all wanders that
89
            // themselves match the text
90
            $mm = new MultiMatch();
91
            $mm->setQuery($data['query']);
92
            $mm->setFields(['title', 'description']);
93
94
            $bool = new BoolQuery();
95
            $bool->addShould($nested);
96
            $bool->addShould($mm);
97
98
            // Wrap it with an outer query to add highlighting to the
99
            // Wander-level query.
100
            $searchQuery = new Query();
101
            $searchQuery->setQuery($bool);
102
103
            $searchQuery->setHighlight(['fields' => [
104
                'title' => [
105
                    'number_of_fragments' => 0,
106
                    'no_match_size' => 1024,
107
                    'pre_tags' => ['<mark>'],
108
                    'post_tags' => ['</mark>']
109
                ],
110
                'description' => [
111
                    'no_match_size' => 200,
112
                    'pre_tags' => ['<mark>'],
113
                    'post_tags' => ['</mark>']
114
                ]
115
            ]]);
116
117
            $results = $wanderFinder->createHybridPaginatorAdapter($searchQuery);
118
            $pagination = $paginator->paginate(
119
                $results,
120
                $request->query->getInt('page', 1),
121
                10
122
            );
123
        }
124
        return $this->render('search/index.html.twig', [
125
            'form' => $form->createView(),
126
            'pagination' => $pagination
127
        ]);
128
    }
129
}
130