TagController   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 72
Duplicated Lines 0 %

Importance

Changes 7
Bugs 1 Features 0
Metric Value
eloc 35
c 7
b 1
f 0
dl 0
loc 72
rs 10
wmc 9

1 Method

Rating   Name   Duplication   Size   Complexity  
B index() 0 56 9
1
<?php
2
3
namespace App\Controller;
4
5
use Elastica\Query;
6
use Elastica\Query\BoolQuery;
7
use Elastica\Query\InnerHits;
8
use Elastica\Query\MultiMatch;
9
use Elastica\Query\Nested;
10
use Elastica\Query\Term;
11
use FOS\ElasticaBundle\Finder\PaginatedFinderInterface;
12
use Knp\Component\Pager\PaginatorInterface;
13
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
14
use Symfony\Component\HttpFoundation\Request;
15
use Symfony\Component\HttpFoundation\Response;
16
use Symfony\Component\Routing\Annotation\Route;
17
18
class TagController extends AbstractController
19
{
20
    /** @var array<string> $translateParam */
21
    private static $translateParam = [
22
        'any'           => 'all tag types',
23
        'hand-tag'      => 'only hand-created tags',
24
        'auto-tag'      => 'only tags created by automatic image recognition',
25
        'text-tag'      => 'only tags created by automatic text recognition'
26
    ];
27
28
    /**
29
     * @Route("/tag/{tag}/{type}",
30
     *  name="tag",
31
     *  methods={"GET"},
32
     *  requirements={"type": "any|hand-tag|auto-tag|text-tag", "page": "\d+"})
33
     */
34
    public function index(
35
        string $tag,
36
        Request $request,
37
        PaginatedFinderInterface $wanderFinder,
38
        PaginatorInterface $paginator,
39
        string $type = "any"
40
    ): Response {
41
        $boolQuery = new BoolQuery();
42
        if ($type === 'hand-tag' || $type === 'any') {
43
            $boolQuery->addShould(new Term(['images.slugifiedTags' => ['value' => $tag]]));
44
        }
45
        if ($type === 'auto-tag' || $type === 'any') {
46
            $boolQuery->addShould(new Term(['images.slugifiedAutoTags' => ['value' => $tag]]));
47
        }
48
        if ($type === 'text-tag' || $type === 'any') {
49
            $boolQuery->addShould(new Term(['images.slugifiedTextTags' => ['value' => $tag]]));
50
        }
51
52
        $boolQuery->setMinimumShouldMatch(1);
53
54
        $nested = new Nested();
55
        $nested->setPath('images');
56
        $nested->setQuery($boolQuery);
57
58
        $innerHits = new InnerHits();
59
        // We want more than the default three inner hits, as there may be several related
60
        // images on a particular wander, but we don't want to bump things up too high otherwise
61
        // an overly-broad search will bring back way too many images even with pagination of
62
        // the outer results.
63
        $innerHits->setSize(10);
64
        $nested->setInnerHits($innerHits);
65
66
        $searchDescription = self::$translateParam[$type];
67
68
        $results = $wanderFinder->createHybridPaginatorAdapter($nested);
69
70
        $perPage = 10; // TODO: Parameterise this results-per-page
71
        $page = $request->query->getInt('page', 1);
72
73
        // Avoid Elastica limit caused by malicious probing "Result window is too large, from + size must be less than or equal to: [10000]"
74
        if (($page * $perPage > 10000) || $page < 1) {
75
            $page = 1;
76
        }
77
78
        $pagination = $paginator->paginate(
79
            $results,
80
            $page,
81
            $perPage
82
        );
83
84
        return $this->render('tag/index.html.twig', [
85
            'tag' => $tag,
86
            // TODO: Take this back out; we'll only need to pass the pagination in the long run. I'm debugging.
87
            'results' => $results,
88
            'pagination' => $pagination,
89
            'search_description' => $searchDescription
90
        ]);
91
    }
92
}
93