Total Complexity | 75 |
Total Lines | 536 |
Duplicated Lines | 0 % |
Changes | 11 | ||
Bugs | 0 | Features | 0 |
Complex classes like TableSelectAdmin often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use TableSelectAdmin, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
20 | class TableSelectAdmin extends AbstractAdmin |
||
21 | { |
||
22 | /** |
||
23 | * Print columns box in select |
||
24 | * @param array $select Result of processSelectColumns()[0] |
||
25 | * @param array $columns Selectable columns |
||
26 | * @param array $options |
||
27 | * @return array |
||
28 | */ |
||
29 | private function getColumnsOptions(array $select, array $columns, array $options): array |
||
30 | { |
||
31 | return [ |
||
32 | 'select' => $select, |
||
33 | 'values' => (array)$options["columns"], |
||
34 | 'columns' => $columns, |
||
35 | 'functions' => $this->driver->functions(), |
||
36 | 'grouping' => $this->driver->grouping(), |
||
37 | ]; |
||
38 | } |
||
39 | |||
40 | /** |
||
41 | * Print search box in select |
||
42 | * |
||
43 | * @param array $columns Selectable columns |
||
44 | * @param array $indexes |
||
45 | * @param array $options |
||
46 | * |
||
47 | * @return array |
||
48 | */ |
||
49 | private function getFiltersOptions(array $columns, array $indexes, array $options): array |
||
50 | { |
||
51 | $fulltexts = []; |
||
52 | foreach ($indexes as $i => $index) { |
||
53 | $fulltexts[$i] = $index->type == "FULLTEXT" ? $this->util->html($options["fulltext"][$i]) : ''; |
||
54 | } |
||
55 | return [ |
||
56 | // 'where' => $where, |
||
57 | 'values' => (array)$options["where"], |
||
58 | 'columns' => $columns, |
||
59 | 'indexes' => $indexes, |
||
60 | 'operators' => $this->driver->operators(), |
||
61 | 'fulltexts' => $fulltexts, |
||
62 | ]; |
||
63 | } |
||
64 | |||
65 | /** |
||
66 | * Print order box in select |
||
67 | * |
||
68 | * @param array $columns Selectable columns |
||
69 | * @param array $options |
||
70 | * |
||
71 | * @return array |
||
72 | */ |
||
73 | private function getSortingOptions(array $columns, array $options): array |
||
74 | { |
||
75 | $values = []; |
||
76 | $descs = (array)$options["desc"]; |
||
77 | foreach ((array)$options["order"] as $key => $value) { |
||
78 | $values[] = [ |
||
79 | 'col' => $value, |
||
80 | 'desc' => $descs[$key] ?? 0, |
||
81 | ]; |
||
82 | } |
||
83 | return [ |
||
84 | // 'order' => $order, |
||
85 | 'values' => $values, |
||
86 | 'columns' => $columns, |
||
87 | ]; |
||
88 | } |
||
89 | |||
90 | /** |
||
91 | * Print limit box in select |
||
92 | * |
||
93 | * @param string $limit Result of processSelectLimit() |
||
94 | * |
||
95 | * @return array |
||
96 | */ |
||
97 | private function getLimitOptions(string $limit): array |
||
98 | { |
||
99 | return ['value' => $this->util->html($limit)]; |
||
100 | } |
||
101 | |||
102 | /** |
||
103 | * Print text length box in select |
||
104 | * |
||
105 | * @param int $textLength Result of processSelectLength() |
||
106 | * |
||
107 | * @return array |
||
108 | */ |
||
109 | private function getLengthOptions($textLength): array |
||
110 | { |
||
111 | return [ |
||
112 | 'value' => $textLength === 0 ? 0 : $this->util->html($textLength), |
||
113 | ]; |
||
114 | } |
||
115 | |||
116 | /** |
||
117 | * Print action box in select |
||
118 | * |
||
119 | * @param array $indexes |
||
120 | * |
||
121 | * @return array |
||
122 | */ |
||
123 | // private function getActionOptions(array $indexes) |
||
124 | // { |
||
125 | // $columns = []; |
||
126 | // foreach ($indexes as $index) { |
||
127 | // $current_key = \reset($index->columns); |
||
128 | // if ($index->type != "FULLTEXT" && $current_key) { |
||
129 | // $columns[$current_key] = 1; |
||
130 | // } |
||
131 | // } |
||
132 | // $columns[""] = 1; |
||
133 | // return ['columns' => $columns]; |
||
134 | // } |
||
135 | |||
136 | /** |
||
137 | * Print command box in select |
||
138 | * |
||
139 | * @return bool whether to print default commands |
||
140 | */ |
||
141 | // private function getCommandOptions() |
||
142 | // { |
||
143 | // return !$this->driver->isInformationSchema($this->driver->database()); |
||
144 | // } |
||
145 | |||
146 | /** |
||
147 | * Print import box in select |
||
148 | * |
||
149 | * @return bool whether to print default import |
||
150 | */ |
||
151 | // private function getImportOptions() |
||
152 | // { |
||
153 | // return !$this->driver->isInformationSchema($this->driver->database()); |
||
154 | // } |
||
155 | |||
156 | /** |
||
157 | * Print extra text in the end of a select form |
||
158 | * |
||
159 | * @param array $emailFields Fields holding e-mails |
||
160 | * @param array $columns Selectable columns |
||
161 | * |
||
162 | * @return array |
||
163 | */ |
||
164 | // private function getEmailOptions(array $emailFields, array $columns) |
||
165 | // { |
||
166 | // } |
||
167 | |||
168 | /** |
||
169 | * @param array $queryOptions |
||
170 | * |
||
171 | * @return int |
||
172 | */ |
||
173 | private function setDefaultOptions(array &$queryOptions): int |
||
174 | { |
||
175 | $defaultOptions = [ |
||
176 | 'columns' => [], |
||
177 | 'where' => [], |
||
178 | 'order' => [], |
||
179 | 'desc' => [], |
||
180 | 'fulltext' => [], |
||
181 | 'limit' => '50', |
||
182 | 'text_length' => '100', |
||
183 | 'page' => '1', |
||
184 | ]; |
||
185 | foreach ($defaultOptions as $name => $value) { |
||
186 | if (!isset($queryOptions[$name])) { |
||
187 | $queryOptions[$name] = $value; |
||
188 | } |
||
189 | } |
||
190 | $page = intval($queryOptions['page']); |
||
191 | if ($page > 0) { |
||
192 | $page -= 1; // Page numbers start at 0 here, instead of 1. |
||
193 | } |
||
194 | $queryOptions['page'] = $page; |
||
195 | return $page; |
||
196 | } |
||
197 | |||
198 | /** |
||
199 | * @param array $fields |
||
200 | * |
||
201 | * @return array |
||
202 | */ |
||
203 | private function getFieldsOptions(array $fields): array |
||
204 | { |
||
205 | $rights = []; // privilege => 0 |
||
206 | $columns = []; // selectable columns |
||
207 | $textLength = 0; |
||
208 | foreach ($fields as $key => $field) { |
||
209 | $name = $this->util->fieldName($field); |
||
210 | if (isset($field->privileges["select"]) && $name != "") { |
||
211 | $columns[$key] = \html_entity_decode(\strip_tags($name), ENT_QUOTES); |
||
212 | if ($this->util->isShortable($field)) { |
||
213 | $textLength = $this->util->processSelectLength(); |
||
214 | } |
||
215 | } |
||
216 | $rights[] = $field->privileges; |
||
217 | } |
||
218 | return [$rights, $columns, $textLength]; |
||
219 | } |
||
220 | |||
221 | /** |
||
222 | * @param array $indexes |
||
223 | * @param array $select |
||
224 | * @param mixed $tableStatus |
||
225 | * |
||
226 | * @return array|null |
||
227 | */ |
||
228 | private function setPrimaryKey(array &$indexes, array $select, $tableStatus) |
||
229 | { |
||
230 | $primary = $unselected = null; |
||
231 | foreach ($indexes as $index) { |
||
232 | if ($index->type == "PRIMARY") { |
||
233 | $primary = \array_flip($index->columns); |
||
234 | $unselected = ($select ? $primary : []); |
||
235 | foreach ($unselected as $key => $val) { |
||
236 | if (\in_array($this->driver->escapeId($key), $select)) { |
||
237 | unset($unselected[$key]); |
||
238 | } |
||
239 | } |
||
240 | break; |
||
241 | } |
||
242 | } |
||
243 | |||
244 | $oid = $tableStatus->oid; |
||
245 | if ($oid && !$primary) { |
||
246 | /*$primary = */$unselected = [$oid => 0]; |
||
247 | $indexes[] = ["type" => "PRIMARY", "columns" => [$oid]]; |
||
248 | } |
||
249 | |||
250 | return $unselected; |
||
251 | } |
||
252 | |||
253 | /** |
||
254 | * @param array $select |
||
255 | * @param array $columns |
||
256 | * @param array $indexes |
||
257 | * @param int $limit |
||
258 | * @param int $textLength |
||
259 | * @param array $queryOptions |
||
260 | * |
||
261 | * @return array |
||
262 | */ |
||
263 | private function getAllOptions(array $select, array $columns, array $indexes, |
||
264 | int $limit, int $textLength, array $queryOptions): array |
||
265 | { |
||
266 | return [ |
||
267 | 'columns' => $this->getColumnsOptions($select, $columns, $queryOptions), |
||
268 | 'filters' => $this->getFiltersOptions($columns, $indexes, $queryOptions), |
||
269 | 'sorting' => $this->getSortingOptions($columns, $queryOptions), |
||
270 | 'limit' => $this->getLimitOptions($limit), |
||
271 | 'length' => $this->getLengthOptions($textLength), |
||
272 | // 'action' => $this->getActionOptions($indexes), |
||
273 | ]; |
||
274 | } |
||
275 | |||
276 | /** |
||
277 | * @param string $table |
||
278 | * @param array $columns |
||
279 | * @param array $fields |
||
280 | * @param array $select |
||
281 | * @param array $group |
||
282 | * @param array $where |
||
283 | * @param array $order |
||
284 | * @param array $unselected |
||
285 | * @param int $limit |
||
286 | * @param int $page |
||
287 | * |
||
288 | * @return TableSelectEntity |
||
289 | */ |
||
290 | private function getSelectEntity(string $table, array $columns, array $fields, array $select, |
||
291 | array $group, array $where, array $order, array $unselected, int $limit, int $page): TableSelectEntity |
||
292 | { |
||
293 | $select2 = $select; |
||
294 | $group2 = $group; |
||
295 | if (!$select2) { |
||
|
|||
296 | $select2[] = "*"; |
||
297 | $convert_fields = $this->driver->convertFields($columns, $fields, $select); |
||
298 | if ($convert_fields) { |
||
299 | $select2[] = \substr($convert_fields, 2); |
||
300 | } |
||
301 | } |
||
302 | foreach ($select as $key => $val) { |
||
303 | $field = $fields[$this->driver->unescapeId($val)] ?? null; |
||
304 | if ($field && ($as = $this->driver->convertField($field))) { |
||
305 | $select2[$key] = "$as AS $val"; |
||
306 | } |
||
307 | } |
||
308 | $isGroup = count($group) < count($select); |
||
309 | if (!$isGroup && $unselected) { |
||
310 | foreach ($unselected as $key => $val) { |
||
311 | $select2[] = $this->driver->escapeId($key); |
||
312 | if ($group2) { |
||
313 | $group2[] = $this->driver->escapeId($key); |
||
314 | } |
||
315 | } |
||
316 | } |
||
317 | |||
318 | // From driver.inc.php |
||
319 | return new TableSelectEntity($table, $select2, $where, $group2, $order, $limit, $page); |
||
320 | } |
||
321 | |||
322 | /** |
||
323 | * Get required data for create/update on tables |
||
324 | * |
||
325 | * @param string $table The table name |
||
326 | * @param array $queryOptions The query options |
||
327 | * |
||
328 | * @return array |
||
329 | * @throws Exception |
||
330 | */ |
||
331 | private function prepareSelect(string $table, array &$queryOptions = []): array |
||
382 | } |
||
383 | |||
384 | /** |
||
385 | * Get required data for create/update on tables |
||
386 | * |
||
387 | * @param string $table The table name |
||
388 | * @param array $queryOptions The query options |
||
389 | * |
||
390 | * @return array |
||
391 | * @throws Exception |
||
392 | */ |
||
393 | public function getSelectData(string $table, array $queryOptions = []): array |
||
394 | { |
||
395 | list($options, $query) = $this->prepareSelect($table, $queryOptions); |
||
396 | |||
397 | $query = $this->util->html($query); |
||
398 | $mainActions = [ |
||
399 | 'select-exec' => $this->trans->lang('Execute'), |
||
400 | 'insert-table' => $this->trans->lang('New item'), |
||
401 | 'select-back' => $this->trans->lang('Back'), |
||
402 | ]; |
||
403 | |||
404 | return compact('mainActions', 'options', 'query'); |
||
405 | } |
||
406 | |||
407 | /** |
||
408 | * Get required data for create/update on tables |
||
409 | * |
||
410 | * @param string $table The table name |
||
411 | * @param array $queryOptions The query options |
||
412 | * |
||
413 | * @return array |
||
414 | * @throws Exception |
||
415 | */ |
||
416 | public function execSelect(string $table, array $queryOptions): array |
||
556 | } |
||
557 | } |
||
558 |
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.