Completed
Push — master ( bcd343...3f8bec )
by Benjamin
02:17
created

ElasticaQuerySorter::fetchData()   C

Complexity

Conditions 7
Paths 5

Size

Total Lines 29
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 3 Features 0
Metric Value
c 4
b 3
f 0
dl 0
loc 29
rs 6.7272
cc 7
eloc 16
nc 5
nop 1
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
        if (empty($this->request)) {
120
            return;
121
        }
122
123
        $pageKey = $this->request->getPathInfo();
124
        $query = $this->request->query;
125
126
        if ($query === null) {
127
            return;
128
        }
129
130
        //Analyzing the session object to see if there is data in it
131
        //If data is given from Request, it will be override the session data
132
        if (array_key_exists($pageKey, $this->sessionData) &&
133
            !$query->has($key) &&
134
            isset($this->sessionData[$pageKey][$key])) {
135
            return $this->sessionData[$pageKey][$key];
136
        }
137
138
        if ($query->has('sortBy')) {
139
            $value = $query->get($key);
140
            $this->sessionData[$pageKey][$key] = $value;
141
            $this->storeSessionData();
142
143
            return $value;
144
        }
145
    }
146
147
    public function storeSessionData()
148
    {
149
        $this->session->set(self::SESSION_QUERY_SORTER, $this->sessionData);
150
    }
151
152
    /**
153
     * Gets the value of session.
154
     *
155
     * @return mixed
156
     */
157
    public function getSession()
158
    {
159
        return $this->session;
160
    }
161
162
    /**
163
     * Gets the value of request.
164
     *
165
     * @return mixed
166
     */
167
    public function getRequest()
168
    {
169
        return $this->request;
170
    }
171
172
    /**
173
     * Gets the value of sessionData.
174
     *
175
     * @return mixed
176
     */
177
    public function getSessionData()
178
    {
179
        return $this->sessionData;
180
    }
181
182
    public function getItemPerPage()
183
    {
184
        return $this->configuration['item_per_page'];
185
    }
186
}
187