Completed
Push — master ( dbfd82...ca8ded )
by Karel
20s queued 16s
created

PaginateElasticaQuerySubscriber::getFromRequest()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 4
cts 4
cp 1
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 2
1
<?php
2
3
/*
4
 * This file is part of the FOSElasticaBundle package.
5
 *
6
 * (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace FOS\ElasticaBundle\Subscriber;
13
14
use FOS\ElasticaBundle\Paginator\PaginatorAdapterInterface;
15
use FOS\ElasticaBundle\Paginator\PartialResultsInterface;
16
use Knp\Component\Pager\Event\ItemsEvent;
17
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
18
use Symfony\Component\HttpFoundation\Request;
19
use Symfony\Component\HttpFoundation\RequestStack;
20
21
class PaginateElasticaQuerySubscriber implements EventSubscriberInterface
22
{
23
    /**
24
     * @var RequestStack
25
     */
26
    private $requestStack;
27
28
    /**
29
     * @param RequestStack $requestStack
30
     */
31 10
    public function __construct(RequestStack $requestStack)
32
    {
33 10
        $this->requestStack = $requestStack;
34 10
    }
35
36
    /**
37
     * @param ItemsEvent $event
38
     */
39 10
    public function items(ItemsEvent $event)
40
    {
41 10
        if ($event->target instanceof PaginatorAdapterInterface) {
42
            // Add sort to query
43 10
            $this->setSorting($event);
44
45
            /** @var $results PartialResultsInterface */
46 9
            $results = $event->target->getResults($event->getOffset(), $event->getLimit());
47
48 9
            $event->count = $results->getTotalHits();
49 9
            $event->items = $results->toArray();
50 9
            $aggregations = $results->getAggregations();
51 9
            if (null != $aggregations) {
52
                $event->setCustomPaginationParameter('aggregations', $aggregations);
53
            }
54
55 9
            $event->stopPropagation();
56
        }
57 9
    }
58
59
    /**
60
     * @return array
61
     */
62
    public static function getSubscribedEvents()
63
    {
64
        return [
65
            'knp_pager.items' => ['items', 1],
66
        ];
67
    }
68
69
    /**
70
     * Adds knp paging sort to query.
71
     *
72
     * @param ItemsEvent $event
73
     */
74 10
    protected function setSorting(ItemsEvent $event)
75
    {
76 10
        $options = $event->options;
77 10
        $sortField = $this->getFromRequest($options['sortFieldParameterName']);
78
79 10
        if (!$sortField && isset($options['defaultSortFieldName'])) {
80 1
            $sortField = $options['defaultSortFieldName'];
81
        }
82
83 10
        if (!empty($sortField)) {
84 8
            $event->target->getQuery()->setSort([
85 8
                $sortField => $this->getSort($sortField, $options),
86
            ]);
87
        }
88 9
    }
89
90 8
    protected function getSort($sortField, array $options = [])
91
    {
92
        $sort = [
93 8
            'order' => $this->getSortDirection($sortField, $options),
94
        ];
95
96 7
        if (isset($options['sortNestedPath'])) {
97 4
            $path = is_callable($options['sortNestedPath']) ?
98 4
                $options['sortNestedPath']($sortField) : $options['sortNestedPath'];
99
100 4
            if (!empty($path)) {
101 4
                $sort['nested_path'] = $path;
102
            }
103
        }
104
105 7
        if (isset($options['sortNestedFilter'])) {
106 2
            $filter = is_callable($options['sortNestedFilter']) ?
107 2
                $options['sortNestedFilter']($sortField) : $options['sortNestedFilter'];
108
109 2
            if (!empty($filter)) {
110 2
                $sort['nested_filter'] = $filter;
111
            }
112
        }
113
114 7
        return $sort;
115
    }
116
117 8
    protected function getSortDirection($sortField, array $options = [])
118
    {
119 8
        $dir = 'asc';
120 8
        $sortDirection = $this->getFromRequest($options['sortDirectionParameterName']);
121
122 8
        if (empty($sortDirection) && isset($options['defaultSortDirection'])) {
123
            $sortDirection = $options['defaultSortDirection'];
124
        }
125
126 8
        if ('desc' === strtolower($sortDirection)) {
127 1
            $dir = 'desc';
128
        }
129
130
        // check if the requested sort field is in the sort whitelist
131 8
        if (isset($options['sortFieldWhitelist']) && !in_array($sortField, $options['sortFieldWhitelist'])) {
132 1
            throw new \UnexpectedValueException(sprintf('Cannot sort by: [%s] this field is not in whitelist', $sortField));
133
        }
134
135 7
        return $dir;
136
    }
137
138
    /**
139
     * @return Request|null
140
     */
141 10
    private function getRequest()
142
    {
143 10
        return $this->requestStack->getCurrentRequest();
144
    }
145
146
    /**
147
     * @param string|null $key
148
     * @return mixed|null
149
     */
150 10
    private function getFromRequest(?string $key)
151
    {
152 10
        if (null !== $request = $this->getRequest()) {
153 9
            return $request->get($key);
154
        }
155
156 1
        return null;
157
    }
158
}
159