Completed
Push — ezp_31440 ( 87ccef )
by
unknown
18:57 queued 03:24
created

QueryRenderController::renderLocationQueryAction()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 2
dl 0
loc 4
rs 10
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace eZ\Publish\Core\MVC\Symfony\Controller;
6
7
use eZ\Publish\API\Repository\SearchService;
8
use eZ\Publish\API\Repository\Values\Content\LocationQuery;
9
use eZ\Publish\Core\MVC\Symfony\View\QueryView;
10
use eZ\Publish\Core\Pagination\Pagerfanta\ContentSearchHitAdapter;
11
use eZ\Publish\Core\Pagination\Pagerfanta\LocationSearchHitAdapter;
12
use eZ\Publish\Core\QueryType\QueryTypeRegistry;
13
use Pagerfanta\Adapter\FixedAdapter;
14
use Pagerfanta\Pagerfanta;
15
use Symfony\Component\HttpFoundation\Request;
16
use Symfony\Component\OptionsResolver\OptionsResolver;
17
18
/**
19
 * Controller used internally by ez_query_X_render_* functions.
20
 *
21
 * @internal
22
 */
23
final class QueryRenderController
24
{
25
    /** @var \eZ\Publish\API\Repository\SearchService */
26
    private $searchService;
27
28
    /** @var \eZ\Publish\Core\QueryType\QueryTypeRegistry */
29
    private $queryTypeRegistry;
30
31
    public function __construct(SearchService $searchService, QueryTypeRegistry $queryTypeRegistry)
32
    {
33
        $this->searchService = $searchService;
34
        $this->queryTypeRegistry = $queryTypeRegistry;
35
    }
36
37
    public function renderContentQueryAction(Request $request, array $options): QueryView
38
    {
39
        return $this->renderQuery($request, $options, 'findContent');
40
    }
41
42
    public function renderContentInfoQueryAction(Request $request, array $options): QueryView
43
    {
44
        return $this->renderQuery($request, $options, 'findContentInfo');
45
    }
46
47
    public function renderLocationQueryAction(Request $request, array $options): QueryView
48
    {
49
        return $this->renderQuery($request, $options, 'findLocation');
50
    }
51
52
    private function renderQuery(Request $request, array $options, string $method): QueryView
53
    {
54
        $options = $this->resolveOptions($options);
55
56
        $queryType = $this->queryTypeRegistry->getQueryType(
57
            $options['query']['query_type']
58
        );
59
60
        $query = $queryType->getQuery($options['query']['parameters']);
61
62
        if ($options['pagination']['enabled']) {
63
            $currentPage = $request->get($options['pagination']['page_param'], 1);
64
65
            if ($query instanceof LocationQuery) {
66
                $results = new Pagerfanta(new LocationSearchHitAdapter($query, $this->searchService));
67
            } else {
68
                $results = new Pagerfanta(new ContentSearchHitAdapter($query, $this->searchService));
69
            }
70
71
            $results->setAllowOutOfRangePages(true);
72
            $results->setMaxPerPage($options['pagination']['limit']);
73
            $results->setCurrentPage($currentPage);
74
        } else {
75
            /** @var \eZ\Publish\API\Repository\Values\Content\Search\SearchResult $searchResults */
76
            $searchResults = $this->searchService->{$method}($query);
77
78
            $results = new Pagerfanta(new FixedAdapter($searchResults->totalCount, $searchResults));
79
        }
80
81
        $view = new QueryView();
82
        $view->setTemplateIdentifier($options['template']);
83
        $view->addParameters([
84
            $options['query']['assign_results_to'] => $results,
85
        ]);
86
87
        return $view;
88
    }
89
90
    private function resolveOptions(array $options): array
91
    {
92
        $resolver = new OptionsResolver();
93
94
        $resolver->setDefault('query', static function (OptionsResolver $resolver): void {
95
            $resolver->setDefaults([
96
                'parameters' => [],
97
                'assign_results_to' => 'items',
98
            ]);
99
100
            $resolver->setRequired(['query_type']);
101
            $resolver->setAllowedTypes('query_type', 'string');
102
            $resolver->setAllowedTypes('parameters', 'array');
103
            $resolver->setAllowedTypes('assign_results_to', 'string');
104
        });
105
106
        $resolver->setDefault('pagination', static function (OptionsResolver $resolver): void {
107
            $resolver->setDefaults([
108
                'enabled' => true,
109
                'limit' => 10,
110
                'page_param' => 'page',
111
            ]);
112
113
            $resolver->setAllowedTypes('enabled', 'boolean');
114
            $resolver->setAllowedTypes('limit', 'int');
115
            $resolver->setAllowedTypes('page_param', 'string');
116
        });
117
118
        $resolver->setRequired('template');
119
        $resolver->setAllowedTypes('template', 'string');
120
        $resolver->setAllowedTypes('query', 'array');
121
122
        return $resolver->resolve($options);
123
    }
124
}
125