Completed
Push — master ( 451970...c83d03 )
by Karel
04:43
created

PaginateElasticaQuerySubscriber::getSort()   C

Complexity

Conditions 7
Paths 25

Size

Total Lines 26
Code Lines 14

Duplication

Lines 16
Ratio 61.54 %

Code Coverage

Tests 18
CRAP Score 7

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 16
loc 26
ccs 18
cts 18
cp 1
rs 6.7272
cc 7
eloc 14
nc 25
nop 2
crap 7
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 9
    public function __construct(RequestStack $requestStack)
32
    {
33 9
        $this->requestStack = $requestStack;
34 9
    }
35
36
    /**
37
     * @param ItemsEvent $event
38
     */
39 9
    public function items(ItemsEvent $event)
40
    {
41 9
        if ($event->target instanceof PaginatorAdapterInterface) {
42
            // Add sort to query
43 9
            $this->setSorting($event);
44
45
            /** @var $results PartialResultsInterface */
46 8
            $results = $event->target->getResults($event->getOffset(), $event->getLimit());
47
48 8
            $event->count = $results->getTotalHits();
49 8
            $event->items = $results->toArray();
50 8
            $aggregations = $results->getAggregations();
51 8
            if (null != $aggregations) {
52
                $event->setCustomPaginationParameter('aggregations', $aggregations);
53
            }
54
55 8
            $event->stopPropagation();
56 8
        }
57 8
    }
58
59
    /**
60
     * Adds knp paging sort to query.
61
     *
62
     * @param ItemsEvent $event
63
     */
64 9
    protected function setSorting(ItemsEvent $event)
65
    {
66 9
        $options = $event->options;
67 9
        $sortField = $this->getRequest()->get($options['sortFieldParameterName']);
68
69 9
        if (!$sortField && isset($options['defaultSortFieldName'])) {
70 1
            $sortField = $options['defaultSortFieldName'];
71 1
        }
72
73 9
        if (!empty($sortField)) {
74 8
            $event->target->getQuery()->setSort([
75 8
                $sortField => $this->getSort($sortField, $options),
76 7
            ]);
77 7
        }
78 8
    }
79
80 8
    protected function getSort($sortField, array $options = [])
81
    {
82
        $sort = [
83 8
            'order' => $this->getSortDirection($sortField, $options),
84 7
        ];
85
86 7 View Code Duplication
        if (isset($options['sortNestedPath'])) {
87 4
            $path = is_callable($options['sortNestedPath']) ?
88 4
                $options['sortNestedPath']($sortField) : $options['sortNestedPath'];
89
90 4
            if (!empty($path)) {
91 4
                $sort['nested_path'] = $path;
92 4
            }
93 4
        }
94
95 7 View Code Duplication
        if (isset($options['sortNestedFilter'])) {
96 2
            $filter = is_callable($options['sortNestedFilter']) ?
97 2
                $options['sortNestedFilter']($sortField) : $options['sortNestedFilter'];
98
99 2
            if (!empty($filter)) {
100 2
                $sort['nested_filter'] = $filter;
101 2
            }
102 2
        }
103
104 7
        return $sort;
105
    }
106
107 8
    protected function getSortDirection($sortField, array $options = [])
108
    {
109 8
        $dir = 'asc';
110 8
        $sortDirection = $this->getRequest()->get($options['sortDirectionParameterName']);
111
112 8
        if (empty($sortDirection) && isset($options['defaultSortDirection'])) {
113
            $sortDirection = $options['defaultSortDirection'];
114
        }
115
116 8
        if ('desc' === strtolower($sortDirection)) {
117 1
            $dir = 'desc';
118 1
        }
119
120
        // check if the requested sort field is in the sort whitelist
121 8
        if (isset($options['sortFieldWhitelist']) && !in_array($sortField, $options['sortFieldWhitelist'])) {
122 1
            throw new \UnexpectedValueException(sprintf('Cannot sort by: [%s] this field is not in whitelist', $sortField));
123
        }
124
125 7
        return $dir;
126
    }
127
128
    /**
129
     * @return Request|null
130
     */
131 9
    private function getRequest()
132
    {
133 9
        return $this->requestStack->getCurrentRequest();
134
    }
135
136
    /**
137
     * @return array
138
     */
139 1
    public static function getSubscribedEvents()
140
    {
141
        return [
142 1
            'knp_pager.items' => ['items', 1],
143 1
        ];
144
    }
145
}
146