ElasticaQuerySorter::getSessionData()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
c 0
b 0
f 0
rs 10
cc 1
eloc 2
nc 1
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, $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