Test Failed
Push — master ( 766a04...43c9a3 )
by Andreas
07:41
created

provider::set_rows()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 1
dl 0
loc 5
ccs 2
cts 2
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
    private client $_client;
27
28
    /**
29
     * The rows to show
30
     */
31
    private ?array $_rows = null;
32
33
    /**
34
     * The total number of rows
35
     */
36
    private ?int $_total_rows = null;
37
38
    /**
39
     * How many items should be shown per page
40
     */
41
    private int $_results_per_page = 20;
42
43
    /**
44
     * The current offset
45
     */
46
    private int $_offset = 0;
47
48
    /**
49
     * The field for sorting
50
     */
51
    private ?string $_sort_field = null;
52
53
    /**
54
     * The direction for sorting (ASC or DESC)
55
     */
56
    private string $_sort_direction = 'ASC';
57
58
    /**
59
     * The grid we're working with
60
     */
61
    private ?grid $_grid = null;
62
63
    /**
64
     * The datatype we're working with
65
     */
66
    private string $_datatype;
67
68
    /**
69
     * The midcom query object
70
     */
71
    private ?midcom_core_query $_query = null;
72
73
    /**
74
     * Search parameters
75
     */
76
    private array $_search = [];
77
78 41
    public function __construct(array|client $source, string $datatype = 'json')
79
    {
80 41
        $this->_datatype = $datatype;
81 41
        if ($source instanceof client) {
0 ignored issues
show
introduced by
$source is never a sub-type of midcom\grid\provider\client.
Loading history...
82 28
            $this->_client = $source;
83 13
        } else {
84 13
            $this->set_rows($source);
85
        }
86
    }
87
88
    /**
89
     * Adds an initial order to the resultset.
90
     *
91
     * This can be overwritten by GET parameters
92
     */
93
    public function add_order(string $field, string $direction = 'ASC')
94
    {
95 5
        $this->_sort_field = $field;
96
        $this->_sort_direction = $direction;
97 5
    }
98 5
99
    public function set_grid(grid $grid)
100
    {
101 10
        $this->_grid = $grid;
102
        $this->_grid->set_provider($this);
103 10
        $this->_datatype = $grid->get_option('datatype');
104 10
    }
105 10
106
    public function get_grid(string $identifier = null) : grid
107
    {
108 21
        if (null !== $identifier) {
109
            $this->_grid = new grid($identifier, $this->_datatype);
110 21
            $this->_grid->set_provider($this);
111 21
            if (!empty($this->_sort_field)) {
112 21
                $this->_grid->set_option('sortname', $this->_sort_field);
113 21
                $this->_grid->set_option('sortorder', strtolower($this->_sort_direction));
114 4
            }
115 4
        }
116
        return $this->_grid;
117
    }
118 21
119
    public function set_rows(array $rows)
120
    {
121 13
        $this->_rows = $rows;
122
        if ($this->_datatype == 'local') {
123 13
            $this->_total_rows = count($this->_rows);
124 13
        }
125 12
    }
126
127
    public function get_rows() : array
128
    {
129 32
        if ($this->_rows === null) {
130
            $this->_get_rows();
131 32
        }
132 20
        return $this->_rows;
133
    }
134 32
135
    public function set_query(midcom_core_query $query)
136
    {
137
        $this->_rows = null;
138
        $this->_total_rows = null;
139
        $this->_query = $query;
140
    }
141
142
    /**
143
     * returns the query (uncached)
144
     */
145
    public function get_query() : midcom_core_query
146
    {
147 22
        if ($this->_datatype == 'json') {
148
            $this->_parse_query($_GET);
149 22
        }
150 8
        $field = $this->_sort_field;
151
        if ($field !== null) {
152 22
            $field = str_replace('index_', '', $field);
153 22
        }
154 5
155
        return $this->_client->get_qb($field, $this->_sort_direction, $this->_search);
156
    }
157 22
158
    public function count_rows() : int
159
    {
160 27
        $this->_total_rows ??= $this->_prepare_query()->count();
161
        return $this->_total_rows;
162 27
    }
163 27
164
    public function get_column_total(string $column)
165
    {
166 3
        $ret = 0;
167
        $rows = $this->get_rows();
168 3
        foreach ($rows as $row) {
169 3
            if (array_key_exists($column, $row)) {
170 3
                $ret += $row[$column];
171 2
            }
172 2
        }
173
        return $ret;
174
    }
175 3
176
    public function setup_grid()
177
    {
178 31
        if ($this->_datatype == 'local') {
179
            $this->_grid->prepend_js($this->_convert_to_localdata());
0 ignored issues
show
Bug introduced by
The method prepend_js() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

179
            $this->_grid->/** @scrutinizer ignore-call */ 
180
                          prepend_js($this->_convert_to_localdata());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
180 31
            $this->_grid->set_option('data', $this->_grid->get_identifier() . '_entries', false);
181 25
            if (null === $this->_get_grid_option('rowNum')) {
182 25
                $this->_grid->set_option('rowNum', $this->count_rows());
183 25
            }
184 25
        }
185
    }
186
187
    public function render()
188
    {
189 6
        match ($this->_datatype) {
190
            'json' => $this->_render_json(),
191 6
            'local' => $this->get_grid()->render()
192 6
        };
193 6
    }
194 6
195
    private function _get_grid_option(string $key, $default = null)
196
    {
197 25
        if (empty($this->_grid)) {
198
            return $default;
199 25
        }
200
        return $this->_grid->get_option($key);
201
    }
202 25
203
    private function _convert_to_localdata() : string
204
    {
205 25
        return "var " . $this->_grid->get_identifier() . '_entries = ' .  json_encode($this->get_rows()) . ";\n";
206
    }
207 25
208
    private function _render_json()
209
    {
210 6
        $rows = $this->get_rows();
211
        $this->_total_rows ??= count($rows);
212 6
213 6
        $response = [
214
            'total' => ceil($this->_total_rows / $this->_results_per_page),
215 6
            'page' => ($this->_offset / $this->_results_per_page) + 1,
216 6
            'records' => $this->_total_rows,
217 6
            'rows' => $rows
218 6
        ];
219 6
        midcom::get()->cache->content->content_type('application/json; charset=UTF-8');
220 6
221 6
        echo json_encode($response);
222
    }
223 6
224
    private function _parse_query(array $query)
225
    {
226 8
        if (!empty($query['rows'])) {
227
            $this->_results_per_page = (int) $query['rows'];
228 8
            if (!empty($query['page'])) {
229
                $this->_offset = ($this->_results_per_page * ($query['page'] - 1));
230
            }
231
        }
232
        if (!empty($query['sidx'])) {
233
            $this->_sort_field = $query['sidx'];
234 8
            $this->_sort_direction = strtoupper($query['sord'] ?? 'ASC');
235
        }
236
        if (   !empty($query['_search'])
237
            && $query['_search'] === 'true') {
238 8
            foreach ($query as $field => $value) {
239 8
                if (in_array($field, ['_search', 'nd', 'page', 'rows', 'sidx', 'sord'])) {
240
                    continue;
241
                }
242
                $this->_search[str_replace('index_', '', $field)] = $value;
243
            }
244
        }
245
    }
246
247
    private function _prepare_query() : midcom_core_query
248
    {
249 22
        $this->_query ??= $this->get_query();
250
        return $this->_query;
251 22
    }
252 22
253
    private function _get_rows()
254
    {
255 20
        $query = $this->_prepare_query();
256
257 20
        $this->_total_rows = $query->count();
258
259 20
        if (   $this->_datatype == 'json'
260
            && !empty($this->_results_per_page)) {
261 20
            $query->set_limit($this->_results_per_page);
262 20
            if (!empty($this->_offset)) {
263 7
                $query->set_offset($this->_offset);
264 7
            }
265
        }
266
        $this->_rows = [];
267
268 20
        if ($query instanceof \midcom_core_collector) {
269
            $items = $query->get_objects();
270 20
        } else {
271 6
            $items = $query->execute();
272
        }
273 14
        foreach ($items as $item) {
274
            $this->_rows[] = $this->_client->get_row($item);
275 20
        }
276 8
    }
277
}
278