Passed
Branch master (a7d334)
by Andreas
21:22
created

provider::count_rows()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 4
nc 2
nop 0
dl 0
loc 7
ccs 5
cts 5
cp 1
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @package midcom.grid
4
 * @author CONTENT CONTROL http://www.contentcontrol-berlin.de/
5
 * @copyright CONTENT CONTROL http://www.contentcontrol-berlin.de/
6
 * @license http://www.gnu.org/licenses/gpl.html GNU General Public License
7
 */
8
9
namespace midcom\grid;
10
11
use midcom\grid\provider\client;
12
use midcom_core_query;
13
use midcom_error;
14
use midcom;
15
16
/**
17
 * Manager for retrieving grid data by AJAX
18
 *
19
 * @package midcom.grid
20
 */
21
class provider
22
{
23
    /**
24
     * The class responsible for getting and formatting rows
25
     *
26
     * @var client
27
     */
28
    private $_client;
29
30
    /**
31
     * The rows to show
32
     *
33
     * @var array
34
     */
35
    private $_rows;
36
37
    /**
38
     * The total number of rows
39
     *
40
     * @var int
41
     */
42
    private $_total_rows;
43
44
    /**
45
     * How many items should be shown per page
46
     *
47
     * @var int
48
     */
49
    private $_results_per_page = 20;
50
51
    /**
52
     * The current offset
53
     *
54
     * @var int
55
     */
56
    private $_offset;
57
58
    /**
59
     * The field for sorting
60
     *
61
     * @var string
62
     */
63
    private $_sort_field;
64
65
    /**
66
     * The direction for sorting (ASC or DESC)
67
     *
68
     * @var string
69
     */
70
    private $_sort_direction = 'ASC';
71
72
    /**
73
     * The grid we're working with
74
     *
75
     * @var grid
76
     */
77
    private $_grid;
78
79
    /**
80
     * The datatype we're working with
81
     *
82
     * @var string
83
     */
84
    private $_datatype;
85
86
    /**
87
     * The midcom query object
88
     *
89
     * @var midcom_core_query
90
     */
91
    private $_query;
92
93
    /**
94
     * Search parameters
95
     *
96
     * @var array
97
     */
98
    private $_search = [];
99
100 41
    public function __construct($source, $datatype = 'json')
101
    {
102 41
        $this->_datatype = $datatype;
103 41
        if ($source instanceof client) {
104 28
            $this->_client = $source;
105 13
        } elseif (is_array($source)) {
106 13
            $this->set_rows($source);
107
        } else {
108
            throw new midcom_error('Unknown source type');
109
        }
110
    }
111
112
    /**
113
     * Adds an initial order to the resultset.
114
     *
115
     * This can be overwritten by GET parameters
116
     */
117 5
    public function add_order(string $field, string $direction = 'ASC')
118
    {
119 5
        $this->_sort_field = $field;
120 5
        $this->_sort_direction = $direction;
121
    }
122
123 10
    public function set_grid(grid $grid)
124
    {
125 10
        $this->_grid = $grid;
126 10
        $this->_grid->set_provider($this);
127 10
        $this->_datatype = $grid->get_option('datatype');
128
    }
129
130 21
    public function get_grid(string $identifier = null) : grid
131
    {
132 21
        if (null !== $identifier) {
133 21
            $this->_grid = new grid($identifier, $this->_datatype);
134 21
            $this->_grid->set_provider($this);
135 21
            if (!empty($this->_sort_field)) {
136 4
                $this->_grid->set_option('sortname', $this->_sort_field);
137 4
                $this->_grid->set_option('sortorder', strtolower($this->_sort_direction));
138
            }
139
        }
140 21
        return $this->_grid;
141
    }
142
143 13
    public function set_rows(array $rows)
144
    {
145 13
        $this->_rows = $rows;
146 13
        if ($this->_datatype == 'local') {
147 12
            $this->_total_rows = count($this->_rows);
148
        }
149
    }
150
151 32
    public function get_rows() : array
152
    {
153 32
        if ($this->_rows === null) {
154 20
            $this->_get_rows();
155
        }
156 32
        return $this->_rows;
157
    }
158
159
    public function set_query(midcom_core_query $query)
160
    {
161
        $this->_rows = null;
162
        $this->_total_rows = null;
163
        $this->_query = $query;
164
    }
165
166
    /**
167
     * returns the query (uncached)
168
     */
169 22
    public function get_query() : midcom_core_query
170
    {
171 22
        if ($this->_datatype == 'json') {
172 8
            $this->_parse_query($_GET);
173
        }
174 22
        $field = $this->_sort_field;
175 22
        if ($field !== null) {
0 ignored issues
show
introduced by
The condition $field !== null is always true.
Loading history...
176 5
            $field = str_replace('index_', '', $field);
177
        }
178
179 22
        return $this->_client->get_qb($field, $this->_sort_direction, $this->_search);
180
    }
181
182 27
    public function count_rows() : int
183
    {
184 27
        if ($this->_total_rows === null) {
185 4
            $qb = $this->_prepare_query();
186 4
            $this->_total_rows = $qb->count();
187
        }
188 27
        return $this->_total_rows;
189
    }
190
191 3
    public function get_column_total(string $column)
192
    {
193 3
        $ret = 0;
194 3
        $rows = $this->get_rows();
195 3
        foreach ($rows as $row) {
196 2
            if (array_key_exists($column, $row)) {
197 2
                $ret += $row[$column];
198
            }
199
        }
200 3
        return $ret;
201
    }
202
203 31
    public function setup_grid()
204
    {
205 31
        if ($this->_datatype == 'local') {
206 25
            $this->_grid->prepend_js($this->_convert_to_localdata());
207 25
            $this->_grid->set_option('data', $this->_grid->get_identifier() . '_entries', false);
208 25
            if (null === $this->_get_grid_option('rowNum')) {
209 25
                $this->_grid->set_option('rowNum', $this->count_rows());
210
            }
211
        }
212
    }
213
214 6
    public function render()
215
    {
216 6
        switch ($this->_datatype) {
217 6
            case 'json':
218 6
                $this->_render_json();
219 6
                break;
220
            case 'local':
221
                $this->get_grid()->render();
222
                break;
223
            default:
224
                debug_add('Datatype ' . $this->_get_grid_option('datatype', 'json') . ' is not supported', MIDCOM_LOG_ERROR);
225
                throw new midcom_error('Unsupported datatype');
226
        }
227
    }
228
229 25
    private function _get_grid_option(string $key, $default = null)
230
    {
231 25
        if (empty($this->_grid)) {
232
            return $default;
233
        }
234 25
        return $this->_grid->get_option($key);
235
    }
236
237 25
    private function _convert_to_localdata() : string
238
    {
239 25
        return "var " . $this->_grid->get_identifier() . '_entries = ' .  json_encode($this->get_rows()) . ";\n";
240
    }
241
242 6
    private function _render_json()
243
    {
244 6
        $rows = $this->get_rows();
245 6
        if ($this->_total_rows === null) {
246
            $this->_total_rows = count($rows);
247
        }
248
249
        $response = [
250 6
            'total' => ceil($this->_total_rows / $this->_results_per_page),
251 6
            'page' => ($this->_offset / $this->_results_per_page) + 1,
252 6
            'records' => $this->_total_rows,
253
            'rows' => $rows
254
        ];
255 6
        midcom::get()->cache->content->content_type('application/json; charset=UTF-8');
256
257 6
        echo json_encode($response);
258
    }
259
260 8
    private function _parse_query(array $query)
261
    {
262 8
        if (!empty($query['rows'])) {
263
            $this->_results_per_page = (int) $query['rows'];
264
            if (!empty($query['page'])) {
265
                $this->_offset = ($this->_results_per_page * ($query['page'] - 1));
266
            }
267
        }
268 8
        if (!empty($query['sidx'])) {
269
            $this->_sort_field = $query['sidx'];
270
            $this->_sort_direction = strtoupper($query['sord']);
271
        }
272 8
        if (   !empty($query['_search'])
273 8
            && $query['_search'] === 'true') {
274
            foreach ($query as $field => $value) {
275
                if (in_array($field, ['_search', 'nd', 'page', 'rows', 'sidx', 'sord'])) {
276
                    continue;
277
                }
278
                $this->_search[str_replace('index_', '', $field)] = $value;
279
            }
280
        }
281
    }
282
283 22
    private function _prepare_query() : midcom_core_query
284
    {
285 22
        if ($this->_query === null) {
286 22
            $this->_query = $this->get_query();
287
        }
288 22
        return $this->_query;
289
    }
290
291 20
    private function _get_rows()
292
    {
293 20
        $query = $this->_prepare_query();
294
295 20
        $this->_total_rows = $query->count();
296
297 20
        if (   $this->_datatype == 'json'
298 20
            && !empty($this->_results_per_page)) {
299 7
            $query->set_limit($this->_results_per_page);
300 7
            if (!empty($this->_offset)) {
301
                $query->set_offset($this->_offset);
302
            }
303
        }
304 20
        $this->_rows = [];
305
306 20
        if ($query instanceof \midcom_core_collector) {
307 6
            $items = $query->get_objects();
308
        } else {
309 14
            $items = $query->execute();
310
        }
311 20
        foreach ($items as $item) {
312 8
            $this->_rows[] = $this->_client->get_row($item);
313
        }
314
    }
315
}
316