Issues (808)

src/midcom/grid/provider.php (2 issues)

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
$source is never a sub-type of midcom\grid\provider\client.
Loading history...
82 28
            $this->_client = $source;
83
        } 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 5
    public function add_order(string $field, string $direction = 'ASC')
94
    {
95 5
        $this->_sort_field = $field;
96 5
        $this->_sort_direction = $direction;
97
    }
98
99 10
    public function set_grid(grid $grid)
100
    {
101 10
        $this->_grid = $grid;
102 10
        $this->_grid->set_provider($this);
103 10
        $this->_datatype = $grid->get_option('datatype');
104
    }
105
106 21
    public function get_grid(?string $identifier = null) : grid
107
    {
108 21
        if (null !== $identifier) {
109 21
            $this->_grid = new grid($identifier, $this->_datatype);
110 21
            $this->_grid->set_provider($this);
111 21
            if (!empty($this->_sort_field)) {
112 4
                $this->_grid->set_option('sortname', $this->_sort_field);
113 4
                $this->_grid->set_option('sortorder', strtolower($this->_sort_direction));
114
            }
115
        }
116 21
        return $this->_grid;
117
    }
118
119 13
    public function set_rows(array $rows)
120
    {
121 13
        $this->_rows = $rows;
122 13
        if ($this->_datatype == 'local') {
123 12
            $this->_total_rows = count($this->_rows);
124
        }
125
    }
126
127 32
    public function get_rows() : array
128
    {
129 32
        if ($this->_rows === null) {
130 20
            $this->_get_rows();
131
        }
132 32
        return $this->_rows;
133
    }
134
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 22
    public function get_query() : midcom_core_query
146
    {
147 22
        if ($this->_datatype == 'json') {
148 8
            $this->_parse_query($_GET);
149
        }
150 22
        $field = $this->_sort_field;
151 22
        if ($field !== null) {
152 5
            $field = str_replace('index_', '', $field);
153
        }
154
155 22
        return $this->_client->get_qb($field, $this->_sort_direction, $this->_search);
156
    }
157
158 27
    public function count_rows() : int
159
    {
160 27
        $this->_total_rows ??= $this->_prepare_query()->count();
161 27
        return $this->_total_rows;
162
    }
163
164 3
    public function get_column_total(string $column)
165
    {
166 3
        $ret = 0;
167 3
        $rows = $this->get_rows();
168 3
        foreach ($rows as $row) {
169 2
            if (array_key_exists($column, $row)) {
170 2
                $ret += $row[$column];
171
            }
172
        }
173 3
        return $ret;
174
    }
175
176 31
    public function setup_grid()
177
    {
178 31
        if ($this->_datatype == 'local') {
179 25
            $this->_grid->prepend_js($this->_convert_to_localdata());
0 ignored issues
show
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 25
            $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
            }
184
        }
185
    }
186
187 6
    public function render()
188
    {
189 6
        match ($this->_datatype) {
190 6
            'json' => $this->_render_json(),
191
            'local' => $this->get_grid()->render()
192 6
        };
193
    }
194
195 25
    private function _get_grid_option(string $key, $default = null)
196
    {
197 25
        return $this->_grid ? $this->_grid->get_option($key) : $default;
198
    }
199
200 25
    private function _convert_to_localdata() : string
201
    {
202 25
        return "var " . $this->_grid->get_identifier() . '_entries = ' .  json_encode($this->get_rows()) . ";\n";
203
    }
204
205 6
    private function _render_json()
206
    {
207 6
        $rows = $this->get_rows();
208 6
        $this->_total_rows ??= count($rows);
209
210 6
        $response = [
211 6
            'total' => ceil($this->_total_rows / $this->_results_per_page),
212 6
            'page' => ($this->_offset / $this->_results_per_page) + 1,
213 6
            'records' => $this->_total_rows,
214 6
            'rows' => $rows
215 6
        ];
216 6
        midcom::get()->header('Content-Type: application/json; charset=UTF-8');
217
218 6
        echo json_encode($response);
219
    }
220
221 8
    private function _parse_query(array $query)
222
    {
223 8
        if (!empty($query['rows'])) {
224
            $this->_results_per_page = (int) $query['rows'];
225
            if (!empty($query['page'])) {
226
                $this->_offset = ($this->_results_per_page * ($query['page'] - 1));
227
            }
228
        }
229 8
        if (!empty($query['sidx'])) {
230
            $this->_sort_field = $query['sidx'];
231
            $this->_sort_direction = strtoupper($query['sord'] ?? 'ASC');
232
        }
233 8
        if (   !empty($query['_search'])
234 8
            && $query['_search'] === 'true') {
235
            foreach ($query as $field => $value) {
236
                if (in_array($field, ['_search', 'nd', 'page', 'rows', 'sidx', 'sord'])) {
237
                    continue;
238
                }
239
                $this->_search[str_replace('index_', '', $field)] = $value;
240
            }
241
        }
242
    }
243
244 22
    private function _prepare_query() : midcom_core_query
245
    {
246 22
        $this->_query ??= $this->get_query();
247 22
        return $this->_query;
248
    }
249
250 20
    private function _get_rows()
251
    {
252 20
        $query = $this->_prepare_query();
253
254 20
        $this->_total_rows = $query->count();
255
256 20
        if (   $this->_datatype == 'json'
257 20
            && !empty($this->_results_per_page)) {
258 7
            $query->set_limit($this->_results_per_page);
259 7
            if (!empty($this->_offset)) {
260
                $query->set_offset($this->_offset);
261
            }
262
        }
263 20
        $this->_rows = [];
264
265 20
        if ($query instanceof \midcom_core_collector) {
266 6
            $items = $query->get_objects();
267
        } else {
268 14
            $items = $query->execute();
269
        }
270 20
        foreach ($items as $item) {
271 8
            $this->_rows[] = $this->_client->get_row($item);
272
        }
273
    }
274
}
275