|
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, $defaultSort = []) |
|
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, $defaultSort); |
|
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, $defaultSort = null) |
|
96
|
|
|
{ |
|
97
|
|
|
$sortBy = explode('-', $this->fetchData('sortBy')); |
|
98
|
|
|
$sortOrder = $this->fetchData('sortOrder'); |
|
99
|
|
|
|
|
100
|
|
|
if ((empty($sortBy) || empty($sortBy[0])) && !empty($defaultSort) && !empty($defaultSort['sortBy'])) { |
|
101
|
|
|
$sortBy = [$defaultSort['sortBy']]; |
|
102
|
|
|
if (!empty($defaultSort['sortOrder'])) { |
|
103
|
|
|
$sortOrder = $defaultSort['sortOrder']; |
|
104
|
|
|
} else { |
|
105
|
|
|
$sortOrder = 'asc'; |
|
106
|
|
|
} |
|
107
|
|
|
} |
|
108
|
|
|
|
|
109
|
|
|
$sort = []; |
|
110
|
|
|
foreach ($sortBy as $element) { |
|
111
|
|
|
if (empty($element) === false && empty($sortOrder) === false) { |
|
112
|
|
|
$sort[$element] = [ |
|
113
|
|
|
'order' => strtolower($sortOrder), |
|
114
|
|
|
'missing' => '_last', |
|
115
|
|
|
]; |
|
116
|
|
|
} |
|
117
|
|
|
} |
|
118
|
|
|
|
|
119
|
|
|
if (!empty($sort)) { |
|
120
|
|
|
$query->setSort($sort); |
|
121
|
|
|
} |
|
122
|
|
|
|
|
123
|
|
|
return $query; |
|
124
|
|
|
} |
|
125
|
|
|
|
|
126
|
|
|
public function fetchData($key) |
|
127
|
|
|
{ |
|
128
|
|
|
if (empty($this->request)) { |
|
129
|
|
|
return; |
|
130
|
|
|
} |
|
131
|
|
|
|
|
132
|
|
|
$pageKey = $this->request->getPathInfo(); |
|
133
|
|
|
$query = $this->request->query; |
|
134
|
|
|
|
|
135
|
|
|
if ($query === null) { |
|
136
|
|
|
return; |
|
137
|
|
|
} |
|
138
|
|
|
|
|
139
|
|
|
//Analyzing the session object to see if there is data in it |
|
140
|
|
|
//If data is given from Request, it will be override the session data |
|
141
|
|
|
if (array_key_exists($pageKey, $this->sessionData) && |
|
142
|
|
|
!$query->has($key) && |
|
143
|
|
|
isset($this->sessionData[$pageKey][$key]) |
|
144
|
|
|
) { |
|
145
|
|
|
return $this->sessionData[$pageKey][$key]; |
|
146
|
|
|
} |
|
147
|
|
|
|
|
148
|
|
|
if ($query->has('sortBy')) { |
|
149
|
|
|
$value = $query->get($key); |
|
150
|
|
|
$this->sessionData[$pageKey][$key] = $value; |
|
151
|
|
|
$this->storeSessionData(); |
|
152
|
|
|
|
|
153
|
|
|
return $value; |
|
154
|
|
|
} |
|
155
|
|
|
} |
|
156
|
|
|
|
|
157
|
|
|
public function storeSessionData() |
|
158
|
|
|
{ |
|
159
|
|
|
$this->session->set(self::SESSION_QUERY_SORTER, $this->sessionData); |
|
160
|
|
|
} |
|
161
|
|
|
|
|
162
|
|
|
/** |
|
163
|
|
|
* Gets the value of session. |
|
164
|
|
|
* |
|
165
|
|
|
* @return mixed |
|
166
|
|
|
*/ |
|
167
|
|
|
public function getSession() |
|
168
|
|
|
{ |
|
169
|
|
|
return $this->session; |
|
170
|
|
|
} |
|
171
|
|
|
|
|
172
|
|
|
/** |
|
173
|
|
|
* Gets the value of request. |
|
174
|
|
|
* |
|
175
|
|
|
* @return mixed |
|
176
|
|
|
*/ |
|
177
|
|
|
public function getRequest() |
|
178
|
|
|
{ |
|
179
|
|
|
return $this->request; |
|
180
|
|
|
} |
|
181
|
|
|
|
|
182
|
|
|
/** |
|
183
|
|
|
* Gets the value of sessionData. |
|
184
|
|
|
* |
|
185
|
|
|
* @return mixed |
|
186
|
|
|
*/ |
|
187
|
|
|
public function getSessionData() |
|
188
|
|
|
{ |
|
189
|
|
|
return $this->sessionData; |
|
190
|
|
|
} |
|
191
|
|
|
|
|
192
|
|
|
public function getItemPerPage() |
|
193
|
|
|
{ |
|
194
|
|
|
return $this->configuration['item_per_page']; |
|
195
|
|
|
} |
|
196
|
|
|
} |
|
197
|
|
|
|