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
![]() |
|||||||
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
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. ![]() |
|||||||
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 |