Completed
Push — master ( e0a17b...273f41 )
by Benjamin
04:30 queued 02:11
created

ElasticaQuerySorter::getPage()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 13
rs 9.2
cc 4
eloc 7
nc 4
nop 0
1
<?php
2
3
namespace Alpixel\Bundle\ElasticaQuerySorterBundle\Services;
4
5
use Elastica\Query;
6
use FOS\ElasticaBundle\Repository;
7
use Symfony\Component\HttpFoundation\Request;
8
use Symfony\Component\HttpFoundation\RequestStack;
9
use Symfony\Component\HttpFoundation\Session\Session;
10
11
/**
12
 * Class used in order to sort and paginate an Abstract Query
13
 * obtained from an elastic search repository
14
 * Data is stored in session to remember user choice.
15
 */
16
class ElasticaQuerySorter
17
{
18
    protected $session;
19
    protected $request;
20
    protected $sessionData;
21
    protected $configuration;
22
23
    const NO_LIMIT             = 99999;
24
    const SESSION_QUERY_SORTER = 'alpixel_elastica_query_sorter';
25
26
    public function __construct(RequestStack $requestStack, Session $session, $configuration)
27
    {
28
        $this->request = $requestStack->getCurrentRequest();
29
        if (empty($this->request)) {
30
            return;
31
        }
32
33
        $this->session = $session;
34
        $this->configuration['item_per_page'] = $configuration;
35
36
        if (isset($this->request->query) && $this->request->query->has('clear_sort') === true) {
37
            $this->session->remove(self::SESSION_QUERY_SORTER);
38
        }
39
40
        //Initializing the data in session
41
        if (!$this->session->has(self::SESSION_QUERY_SORTER)) {
42
            $this->sessionData = [];
43
        } else {
44
            $this->sessionData = $this->session->get(self::SESSION_QUERY_SORTER);
45
        }
46
    }
47
48
    public function sort(Repository $repository, Query $query, $nbPerPage = null)
49
    {
50
        if ($nbPerPage === null) {
51
            $nbPerPage = $this->getItemPerPage();
52
        }
53
54
        //Creating the main elastica query
55
        $query->setFields(['_id']);
56
57
        //Analysing the request and the session data to add sorting
58
        $this->addSort($query);
59
60
        //Creating the paginator with the given repository
61
        $paginator = $repository->findPaginated($query);
62
        //If this a new sortBy, then we reset the currentPage to 1
63
        $paginator->setCurrentPage($this->getCurrentPage());
64
65
        $paginator->setMaxPerPage($nbPerPage);
66
67
        return $paginator;
68
    }
69
70
    protected function getCurrentPage()
71
    {
72
        $page = 1;
73
74
        if (!empty($this->request) && $this->request->getRealMethod() === 'GET') {
75
            $page = $this->getPage();
76
        }
77
78
        return $page;
79
    }
80
81
    protected function getPage()
82
    {
83
        $nbPage = null;
84
        if ($this->request->query->has('page')) {
85
            $nbPage = $this->request->query->get('page');
86
        }
87
88
        if (empty($nbPage) || !is_numeric($nbPage)) {
89
            return 1;
90
        }
91
92
        return $nbPage;
93
    }
94
95
    protected function addSort(Query &$query)
96
    {
97
        $sortBy = explode('-', $this->fetchData('sortBy'));
98
        $sortOrder = $this->fetchData('sortOrder');
99
100
        $sort = [];
101
        foreach ($sortBy as $element) {
102
            if (empty($element) === false && empty($sortOrder) === false) {
103
                $sort[$element] = [
104
                    'order'     => strtolower($sortOrder),
105
                    'missing'   => '_last',
106
                ];
107
            }
108
        }
109
110
        if (!empty($sort)) {
111
            $query->setSort($sort);
112
        }
113
114
        return $query;
115
    }
116
117
    public function fetchData($key)
118
    {
119
        $pageKey = $this->request->getPathInfo();
120
        $query   = $this->request->query;
121
122
        if ($query === null) {
123
            return;
124
        }
125
126
        //Analyzing the session object to see if there is data in it
127
        //If data is given from Request, it will be override the session data
128
        if (array_key_exists($pageKey, $this->sessionData) &&
129
            !$query->has($key) &&
130
            isset($this->sessionData[$pageKey][$key])) {
131
                return $this->sessionData[$pageKey][$key];
132
        }
133
134
        if ($query->has('sortBy')) {
135
            $value = $query->get($key);
136
            $this->sessionData[$pageKey][$key] = $value;
137
            $this->storeSessionData();
138
139
            return $value;
140
        }
141
    }
142
143
    public function storeSessionData()
144
    {
145
        $this->session->set(self::SESSION_QUERY_SORTER, $this->sessionData);
146
    }
147
148
    /**
149
     * Gets the value of session.
150
     *
151
     * @return mixed
152
     */
153
    public function getSession()
154
    {
155
        return $this->session;
156
    }
157
158
    /**
159
     * Gets the value of request.
160
     *
161
     * @return mixed
162
     */
163
    public function getRequest()
164
    {
165
        return $this->request;
166
    }
167
168
    /**
169
     * Gets the value of sessionData.
170
     *
171
     * @return mixed
172
     */
173
    public function getSessionData()
174
    {
175
        return $this->sessionData;
176
    }
177
178
    public function getItemPerPage()
179
    {
180
        return $this->configuration['item_per_page'];
181
    }
182
}
183