Completed
Push — ezp_31107 ( 816f32...9177e0 )
by
unknown
220:54 queued 209:22
created

QueryRenderController::resolveOptions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 1
dl 0
loc 34
rs 9.376
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
5
 * @license For full copyright and license information view LICENSE file distributed with this source code.
6
 */
7
declare(strict_types=1);
8
9
namespace eZ\Publish\Core\MVC\Symfony\Controller;
10
11
use eZ\Publish\Core\MVC\Symfony\View\QueryView;
12
use eZ\Publish\Core\Pagination\Pagerfanta\AdapterFactory\SearchHitAdapterFactoryInterface;
13
use eZ\Publish\Core\Query\QueryFactoryInterface;
14
use Pagerfanta\Adapter\AdapterInterface;
15
use Pagerfanta\Pagerfanta;
16
use Symfony\Component\HttpFoundation\Request;
17
use Symfony\Component\OptionsResolver\OptionsResolver;
18
19
/**
20
 * Controller used internally by ez_query_*_render and ez_query_*_render_* functions.
21
 *
22
 * @internal
23
 */
24
final class QueryRenderController
25
{
26
    /** @var \eZ\Publish\Core\Query\QueryFactoryInterface */
27
    private $queryFactory;
28
29
    /** @var \eZ\Publish\Core\Pagination\Pagerfanta\AdapterFactory\SearchHitAdapterFactoryInterface */
30
    private $searchHitAdapterFactory;
31
32
    public function __construct(
33
        QueryFactoryInterface $queryFactory,
34
        SearchHitAdapterFactoryInterface $searchHitAdapterFactory
35
    ) {
36
        $this->queryFactory = $queryFactory;
37
        $this->searchHitAdapterFactory = $searchHitAdapterFactory;
38
    }
39
40
    public function renderQuery(Request $request, array $options): QueryView
41
    {
42
        $options = $this->resolveOptions($options);
43
44
        $results = new Pagerfanta($this->getAdapter($options));
45
        if ($options['pagination']['enabled']) {
46
            $currentPage = $request->get($options['pagination']['page_param'], 1);
47
48
            $results->setAllowOutOfRangePages(true);
49
            $results->setMaxPerPage($options['pagination']['limit']);
50
            $results->setCurrentPage($currentPage);
51
        }
52
53
        return $this->createQueryView(
54
            $options['template'],
55
            $options['query']['assign_results_to'],
56
            $results
57
        );
58
    }
59
60
    private function resolveOptions(array $options): array
61
    {
62
        $resolver = new OptionsResolver();
63
64
        $resolver->setDefault('query', static function (OptionsResolver $resolver): void {
65
            $resolver->setDefaults([
66
                'parameters' => [],
67
                'assign_results_to' => 'items',
68
            ]);
69
70
            $resolver->setRequired(['query_type']);
71
            $resolver->setAllowedTypes('query_type', 'string');
72
            $resolver->setAllowedTypes('parameters', 'array');
73
            $resolver->setAllowedTypes('assign_results_to', 'string');
74
        });
75
76
        $resolver->setDefault('pagination', static function (OptionsResolver $resolver): void {
77
            $resolver->setDefaults([
78
                'enabled' => true,
79
                'limit' => 10,
80
                'page_param' => 'page',
81
            ]);
82
83
            $resolver->setAllowedTypes('enabled', 'boolean');
84
            $resolver->setAllowedTypes('limit', 'int');
85
            $resolver->setAllowedTypes('page_param', 'string');
86
        });
87
88
        $resolver->setRequired('template');
89
        $resolver->setAllowedTypes('template', 'string');
90
        $resolver->setAllowedTypes('query', 'array');
91
92
        return $resolver->resolve($options);
93
    }
94
95
    private function getAdapter(array $options): AdapterInterface
96
    {
97
        $query = $this->queryFactory->create(
98
            $options['query']['query_type'],
99
            $options['query']['parameters']
100
        );
101
102
        if ($options['pagination']['enabled']) {
103
            return $this->searchHitAdapterFactory->createAdapter($query);
104
        }
105
106
        return $this->searchHitAdapterFactory->createFixedAdapter($query);
107
    }
108
109
    private function createQueryView(string $template, string $assignResultsTo, iterable $results): QueryView
110
    {
111
        $view = new QueryView();
112
        $view->setTemplateIdentifier($template);
113
        $view->addParameters([
114
            $assignResultsTo => $results,
115
        ]);
116
117
        return $view;
118
    }
119
}
120