Total Complexity | 86 |
Total Lines | 631 |
Duplicated Lines | 0 % |
Changes | 5 | ||
Bugs | 0 | Features | 0 |
Complex classes like TableAdmin 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 TableAdmin, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
13 | class TableAdmin extends AbstractAdmin |
||
14 | { |
||
15 | /** |
||
16 | * The current table status |
||
17 | * |
||
18 | * @var mixed |
||
19 | */ |
||
20 | protected $tableStatus = null; |
||
21 | |||
22 | /** |
||
23 | * @var array |
||
24 | */ |
||
25 | protected $referencableTables = []; |
||
26 | |||
27 | /** |
||
28 | * @var array |
||
29 | */ |
||
30 | protected $foreignKeys = []; |
||
31 | |||
32 | /** |
||
33 | * Get the current table status |
||
34 | * |
||
35 | * @param string $table |
||
36 | * |
||
37 | * @return mixed |
||
38 | */ |
||
39 | protected function status(string $table) |
||
40 | { |
||
41 | if (!$this->tableStatus) { |
||
42 | $this->tableStatus = $this->driver->tableStatusOrName($table, true); |
||
43 | } |
||
44 | return $this->tableStatus; |
||
45 | } |
||
46 | |||
47 | /** |
||
48 | * Print links after select heading |
||
49 | * Copied from selectLinks() in adminer.inc.php |
||
50 | * |
||
51 | * @param string $set New item options, NULL for no new item |
||
52 | * |
||
53 | * @return array |
||
54 | */ |
||
55 | protected function getTableLinks($set = null) |
||
56 | { |
||
57 | $links = [ |
||
58 | 'select' => $this->trans->lang('Select data'), |
||
59 | ]; |
||
60 | if ($this->driver->support('table') || $this->driver->support('indexes')) { |
||
61 | $links['table'] = $this->trans->lang('Show structure'); |
||
62 | } |
||
63 | if ($this->driver->support('table')) { |
||
64 | $links['alter'] = $this->trans->lang('Alter table'); |
||
65 | } |
||
66 | if ($set !== null) { |
||
67 | $links['edit'] = $this->trans->lang('New item'); |
||
68 | } |
||
69 | // $links['docs'] = \doc_link([$this->driver->jush() => $this->driver->tableHelp($name)], '?'); |
||
70 | |||
71 | return $links; |
||
72 | } |
||
73 | |||
74 | /** |
||
75 | * Get details about a table |
||
76 | * |
||
77 | * @param string $table The table name |
||
78 | * |
||
79 | * @return array |
||
80 | */ |
||
81 | public function getTableInfo(string $table) |
||
82 | { |
||
83 | $mainActions = [ |
||
84 | 'edit-table' => $this->trans->lang('Alter table'), |
||
85 | 'drop-table' => $this->trans->lang('Drop table'), |
||
86 | 'select-table' => $this->trans->lang('Select'), |
||
87 | 'insert-table' => $this->trans->lang('New item'), |
||
88 | ]; |
||
89 | |||
90 | // From table.inc.php |
||
91 | $status = $this->status($table); |
||
92 | $name = $this->util->tableName($status); |
||
93 | $title = $this->trans->lang('Table') . ': ' . ($name != '' ? $name : $this->util->html($table)); |
||
94 | |||
95 | $comment = $status->comment; |
||
96 | |||
97 | $tabs = [ |
||
98 | 'fields' => $this->trans->lang('Columns'), |
||
99 | // 'indexes' => $this->trans->lang('Indexes'), |
||
100 | // 'foreign-keys' => $this->trans->lang('Foreign keys'), |
||
101 | // 'triggers' => $this->trans->lang('Triggers'), |
||
102 | ]; |
||
103 | if ($this->driver->isView($status)) { |
||
104 | if ($this->driver->support('view_trigger')) { |
||
105 | $tabs['triggers'] = $this->trans->lang('Triggers'); |
||
106 | } |
||
107 | } else { |
||
108 | if ($this->driver->support('indexes')) { |
||
109 | $tabs['indexes'] = $this->trans->lang('Indexes'); |
||
110 | } |
||
111 | if ($this->driver->supportForeignKeys($status)) { |
||
112 | $tabs['foreign-keys'] = $this->trans->lang('Foreign keys'); |
||
113 | } |
||
114 | if ($this->driver->support('trigger')) { |
||
115 | $tabs['triggers'] = $this->trans->lang('Triggers'); |
||
116 | } |
||
117 | } |
||
118 | |||
119 | return \compact('mainActions', 'title', 'comment', 'tabs'); |
||
120 | } |
||
121 | |||
122 | /** |
||
123 | * Get the fields of a table |
||
124 | * |
||
125 | * @param string $table The table name |
||
126 | * |
||
127 | * @return array |
||
128 | */ |
||
129 | public function getTableFields(string $table) |
||
130 | { |
||
131 | // From table.inc.php |
||
132 | $fields = $this->driver->fields($table); |
||
133 | if (empty($fields)) { |
||
134 | throw new Exception($this->driver->error()); |
||
135 | } |
||
136 | |||
137 | $mainActions = $this->getTableLinks(); |
||
138 | |||
139 | $tabs = [ |
||
140 | 'fields' => $this->trans->lang('Columns'), |
||
141 | // 'indexes' => $this->trans->lang('Indexes'), |
||
142 | // 'foreign-keys' => $this->trans->lang('Foreign keys'), |
||
143 | // 'triggers' => $this->trans->lang('Triggers'), |
||
144 | ]; |
||
145 | if ($this->driver->support('indexes')) { |
||
146 | $tabs['indexes'] = $this->trans->lang('Indexes'); |
||
147 | } |
||
148 | if ($this->driver->supportForeignKeys($this->status($table))) { |
||
149 | $tabs['foreign-keys'] = $this->trans->lang('Foreign keys'); |
||
150 | } |
||
151 | if ($this->driver->support('trigger')) { |
||
152 | $tabs['triggers'] = $this->trans->lang('Triggers'); |
||
153 | } |
||
154 | |||
155 | $headers = [ |
||
156 | $this->trans->lang('Name'), |
||
157 | $this->trans->lang('Type'), |
||
158 | $this->trans->lang('Collation'), |
||
159 | ]; |
||
160 | $hasComment = $this->driver->support('comment'); |
||
161 | if ($hasComment) { |
||
162 | $headers[] = $this->trans->lang('Comment'); |
||
163 | } |
||
164 | |||
165 | $details = []; |
||
166 | foreach ($fields as $field) { |
||
167 | $type = $this->util->html($field->fullType); |
||
168 | if ($field->null) { |
||
169 | $type .= ' <i>nullable</i>'; // ' <i>NULL</i>'; |
||
170 | } |
||
171 | if ($field->autoIncrement) { |
||
172 | $type .= ' <i>' . $this->trans->lang('Auto Increment') . '</i>'; |
||
173 | } |
||
174 | if ($field->default !== '') { |
||
175 | $type .= /*' ' . $this->trans->lang('Default value') .*/ ' [<b>' . $this->util->html($field->default) . '</b>]'; |
||
176 | } |
||
177 | $detail = [ |
||
178 | 'name' => $this->util->html($field->name), |
||
179 | 'type' => $type, |
||
180 | 'collation' => $this->util->html($field->collation), |
||
181 | ]; |
||
182 | if ($hasComment) { |
||
183 | $detail['comment'] = $this->util->html($field->comment); |
||
184 | } |
||
185 | |||
186 | $details[] = $detail; |
||
187 | } |
||
188 | |||
189 | return \compact('mainActions', 'headers', 'details'); |
||
190 | } |
||
191 | |||
192 | /** |
||
193 | * Get the indexes of a table |
||
194 | * |
||
195 | * @param string $table The table name |
||
196 | * |
||
197 | * @return array|null |
||
198 | */ |
||
199 | public function getTableIndexes(string $table) |
||
240 | } |
||
241 | |||
242 | /** |
||
243 | * Get the foreign keys of a table |
||
244 | * |
||
245 | * @param string $table The table name |
||
246 | * |
||
247 | * @return array|null |
||
248 | */ |
||
249 | public function getTableForeignKeys(string $table) |
||
250 | { |
||
251 | $status = $this->status($table); |
||
252 | if (!$this->driver->supportForeignKeys($status)) { |
||
253 | return null; |
||
254 | } |
||
255 | |||
256 | // From table.inc.php |
||
257 | $mainActions = [ |
||
258 | $this->trans->lang('Add foreign key'), |
||
259 | ]; |
||
260 | |||
261 | $headers = [ |
||
262 | $this->trans->lang('Name'), |
||
263 | $this->trans->lang('Source'), |
||
264 | $this->trans->lang('Target'), |
||
265 | $this->trans->lang('ON DELETE'), |
||
266 | $this->trans->lang('ON UPDATE'), |
||
267 | ]; |
||
268 | |||
269 | $foreignKeys = $this->driver->foreignKeys($table); |
||
270 | $details = []; |
||
271 | // From table.inc.php |
||
272 | foreach ($foreignKeys as $name => $foreignKey) { |
||
273 | $target = ''; |
||
274 | if ($foreignKey->database != '') { |
||
275 | $target .= '<b>' . $this->util->html($foreignKey->database) . '</b>.'; |
||
276 | } |
||
277 | if ($foreignKey->schema != '') { |
||
278 | $target .= '<b>' . $this->util->html($foreignKey->schema) . '</b>.'; |
||
279 | } |
||
280 | $target = $this->util->html($foreignKey->table) . |
||
281 | '(' . \implode(', ', \array_map(function ($key) { |
||
282 | return $this->util->html($key); |
||
283 | }, $foreignKey->target)) . ')'; |
||
284 | $details[] = [ |
||
285 | 'name' => $this->util->html($name), |
||
286 | 'source' => '<i>' . \implode( |
||
287 | '</i>, <i>', |
||
288 | \array_map(function ($key) { |
||
289 | return $this->util->html($key); |
||
290 | }, $foreignKey->source) |
||
291 | ) . '</i>', |
||
292 | 'target' => $target, |
||
293 | 'onDelete' => $this->util->html($foreignKey->onDelete), |
||
294 | 'onUpdate' => $this->util->html($foreignKey->onUpdate), |
||
295 | ]; |
||
296 | } |
||
297 | |||
298 | return \compact('mainActions', 'headers', 'details'); |
||
299 | } |
||
300 | |||
301 | /** |
||
302 | * Get the triggers of a table |
||
303 | * |
||
304 | * @param string $table The table name |
||
305 | * |
||
306 | * @return array|null |
||
307 | */ |
||
308 | public function getTableTriggers(string $table) |
||
309 | { |
||
310 | if (!$this->driver->support('trigger')) { |
||
311 | return null; |
||
312 | } |
||
313 | |||
314 | $mainActions = [ |
||
315 | $this->trans->lang('Add trigger'), |
||
316 | ]; |
||
317 | |||
318 | $headers = [ |
||
319 | $this->trans->lang('Name'), |
||
320 | ' ', |
||
321 | ' ', |
||
322 | ' ', |
||
323 | ]; |
||
324 | |||
325 | $details = []; |
||
326 | // From table.inc.php |
||
327 | $triggers = $this->driver->triggers($table); |
||
328 | foreach ($triggers as $name => $trigger) { |
||
329 | $details[] = [ |
||
330 | $this->util->html($trigger->timing), |
||
331 | $this->util->html($trigger->event), |
||
332 | $this->util->html($name), |
||
333 | $this->trans->lang('Alter'), |
||
334 | ]; |
||
335 | } |
||
336 | |||
337 | return \compact('mainActions', 'headers', 'details'); |
||
338 | } |
||
339 | |||
340 | /** |
||
341 | * Get foreign keys |
||
342 | * |
||
343 | * @param string $table The table name |
||
344 | * |
||
345 | * @return void |
||
346 | */ |
||
347 | private function getForeignKeys(string $table = '') |
||
348 | { |
||
349 | $this->referencableTables = $this->driver->referencableTables($table); |
||
350 | $this->foreignKeys = []; |
||
351 | foreach ($this->referencableTables as $tableName => $field) { |
||
352 | $name = \str_replace('`', '``', $tableName) . '`' . \str_replace('`', '``', $field->name); |
||
353 | // not escapeId() - used in JS |
||
354 | $this->foreignKeys[$name] = $tableName; |
||
355 | } |
||
356 | } |
||
357 | |||
358 | /** |
||
359 | * Get field types |
||
360 | * |
||
361 | * @param string $type The type name |
||
362 | * |
||
363 | * @return array |
||
364 | */ |
||
365 | public function getFieldTypes(string $type = '') |
||
366 | { |
||
367 | // From includes/editing.inc.php |
||
368 | $extraTypes = []; |
||
369 | if ($type && !$this->driver->typeExists($type) && !isset($this->foreignKeys[$type]) && |
||
370 | !\array_key_exists($this->trans->lang('Current'), $extraTypes)) { |
||
371 | $extraTypes[$this->trans->lang('Current')] = [$type]; |
||
372 | } |
||
373 | if ($this->foreignKeys) { |
||
|
|||
374 | $this->driver->setStructuredType($this->trans->lang('Foreign keys'), $this->foreignKeys); |
||
375 | } |
||
376 | return \array_merge($extraTypes, $this->driver->structuredTypes()); |
||
377 | } |
||
378 | |||
379 | /** |
||
380 | * Get required data for create/update on tables |
||
381 | * |
||
382 | * @param string $table The table name |
||
383 | * |
||
384 | * @return array |
||
385 | */ |
||
386 | public function getTableData(string $table = '') |
||
387 | { |
||
388 | $mainActions = [ |
||
389 | 'table-save' => $this->trans->lang('Save'), |
||
390 | 'table-cancel' => $this->trans->lang('Cancel'), |
||
391 | ]; |
||
392 | |||
393 | // From create.inc.php |
||
394 | $status = []; |
||
395 | $fields = []; |
||
396 | if ($table !== '') { |
||
397 | $status = $this->driver->tableStatus($table); |
||
398 | if (!$status) { |
||
399 | throw new Exception($this->trans->lang('No tables.')); |
||
400 | } |
||
401 | $fields = $this->driver->fields($table); |
||
402 | } |
||
403 | |||
404 | $this->getForeignKeys($table); |
||
405 | |||
406 | $hasAutoIncrement = false; |
||
407 | foreach ($fields as &$field) { |
||
408 | $hasAutoIncrement = $hasAutoIncrement || $field->autoIncrement; |
||
409 | $field->hasDefault = $field->default !== null; |
||
410 | if (\preg_match('~^CURRENT_TIMESTAMP~i', $field->onUpdate)) { |
||
411 | $field->onUpdate = 'CURRENT_TIMESTAMP'; |
||
412 | } |
||
413 | |||
414 | $type = $field->type; |
||
415 | $field->types = $this->getFieldTypes($type); |
||
416 | $field->lengthRequired = !$field->length && \preg_match('~var(char|binary)$~', $type); |
||
417 | $field->collationHidden = !\preg_match('~(char|text|enum|set)$~', $type); |
||
418 | $field->unsignedHidden = !(!$type || \preg_match($this->driver->numberRegex(), $type)); |
||
419 | $field->onUpdateHidden = !\preg_match('~timestamp|datetime~', $type); |
||
420 | $field->onDeleteHidden = !\preg_match('~`~', $type); |
||
421 | } |
||
422 | $options = [ |
||
423 | 'hasAutoIncrement' => $hasAutoIncrement, |
||
424 | 'onUpdate' => ['CURRENT_TIMESTAMP'], |
||
425 | 'onDelete' => $this->driver->onActions(), |
||
426 | ]; |
||
427 | |||
428 | $collations = $this->driver->collations(); |
||
429 | $engines = $this->driver->engines(); |
||
430 | $support = [ |
||
431 | 'columns' => $this->driver->support('columns'), |
||
432 | 'comment' => $this->driver->support('comment'), |
||
433 | 'partitioning' => $this->driver->support('partitioning'), |
||
434 | 'move_col' => $this->driver->support('move_col'), |
||
435 | 'drop_col' => $this->driver->support('drop_col'), |
||
436 | ]; |
||
437 | |||
438 | $foreignKeys = $this->foreignKeys; |
||
439 | $unsigned = $this->driver->unsigned(); |
||
440 | // Give the var a better name |
||
441 | $table = $status; |
||
442 | return \compact('mainActions', 'table', 'foreignKeys', 'fields', |
||
443 | 'options', 'collations', 'engines', 'support', 'unsigned'); |
||
444 | } |
||
445 | |||
446 | /** |
||
447 | * Get fields for a new column |
||
448 | * |
||
449 | * @return TableFieldEntity |
||
450 | */ |
||
451 | public function getTableField() |
||
452 | { |
||
453 | $this->getForeignKeys(); |
||
454 | $field = new TableFieldEntity(); |
||
455 | $field->types = $this->getFieldTypes(); |
||
456 | return $field; |
||
457 | } |
||
458 | |||
459 | /** |
||
460 | * Create or alter a table |
||
461 | * |
||
462 | * @param array $values The table values |
||
463 | * @param string $table The table name |
||
464 | * @param array $origFields The table fields |
||
465 | * |
||
466 | * @return array |
||
467 | */ |
||
468 | private function createOrAlterTable(array $values, string $table = '', array $origFields = []) |
||
469 | { |
||
470 | // From create.inc.php |
||
471 | $values['fields'] = (array)$values['fields']; |
||
472 | if ($values['autoIncrementCol']) { |
||
473 | $values['fields'][$values['autoIncrementCol']]['autoIncrement'] = true; |
||
474 | } |
||
475 | |||
476 | $fields = []; |
||
477 | $allFields = []; |
||
478 | $useAllFields = false; |
||
479 | $foreign = []; |
||
480 | $origField = \reset($origFields); |
||
481 | $after = ' FIRST'; |
||
482 | |||
483 | $this->getForeignKeys(); |
||
484 | |||
485 | foreach ($values['fields'] as $key => $field) { |
||
486 | $orig = $field['orig']; |
||
487 | $field = TableFieldEntity::make($field); |
||
488 | $foreignKey = $this->foreignKeys[$field->type] ?? null; |
||
489 | //! can collide with user defined type |
||
490 | $typeField = ($foreignKey === null ? $field : |
||
491 | TableFieldEntity::make($this->referencableTables[$foreignKey])); |
||
492 | // Originally, deleted fields have the "field" field set to an empty string. |
||
493 | // But in our implementation, the "name" field is not set. |
||
494 | if ($field->name != '') { |
||
495 | $field->autoIncrement = ($key == $values['autoIncrementCol']); |
||
496 | |||
497 | $processedField = $this->util->processField($field, $typeField); |
||
498 | $allFields[] = [$orig, $processedField, $after]; |
||
499 | if (!$origField || $field->changed($origField)) { |
||
500 | $fields[] = [$orig, $processedField, $after]; |
||
501 | if ($orig != '' || $after) { |
||
502 | $useAllFields = true; |
||
503 | } |
||
504 | } |
||
505 | if ($foreignKey !== null) { |
||
506 | $fkey = new ForeignKeyEntity(); |
||
507 | $fkey->table = $this->foreignKeys[$field->type]; |
||
508 | $fkey->source = [$field->name]; |
||
509 | $fkey->target = [$typeField['field']]; |
||
510 | $fkey->onDelete = $field->onDelete; |
||
511 | $foreign[$this->driver->escapeId($field->name)] = |
||
512 | ($table != '' && $this->driver->jush() != 'sqlite' ? 'ADD' : ' ') . |
||
513 | $this->driver->formatForeignKey($fkey); |
||
514 | } |
||
515 | $after = ' AFTER ' . $this->driver->escapeId($field->name); |
||
516 | } elseif ($orig != '') { |
||
517 | // A missing "name" field and a not empty "orig" field means the column is to be dropped. |
||
518 | // We also append null in the array because the drivers code accesses field at position 1. |
||
519 | $useAllFields = true; |
||
520 | $fields[] = [$orig, null]; |
||
521 | } |
||
522 | if ($orig != '') { |
||
523 | $origField = \next($origFields); |
||
524 | if (!$origField) { |
||
525 | $after = ''; |
||
526 | } |
||
527 | } |
||
528 | } |
||
529 | |||
530 | // For now, partitioning is not implemented |
||
531 | $partitioning = ''; |
||
532 | // if($partition_by[$values['partition_by']]) |
||
533 | // { |
||
534 | // $partitions = []; |
||
535 | // if($values['partition_by'] == 'RANGE' || $values['partition_by'] == 'LIST') |
||
536 | // { |
||
537 | // foreach(\array_filter($values['partition_names']) as $key => $val) |
||
538 | // { |
||
539 | // $value = $values['partition_values'][$key]; |
||
540 | // $partitions[] = "\n PARTITION " . $this->driver->escapeId($val) . |
||
541 | // ' VALUES ' . ($values['partition_by'] == 'RANGE' ? 'LESS THAN' : 'IN') . |
||
542 | // ($value != '' ? ' ($value)' : ' MAXVALUE'); //! SQL injection |
||
543 | // } |
||
544 | // } |
||
545 | // $partitioning .= "\nPARTITION BY $values[partition_by]($values[partition])" . |
||
546 | // ($partitions // $values['partition'] can be expression, not only column |
||
547 | // ? ' (' . \implode(',', $partitions) . "\n)" |
||
548 | // : ($values['partitions'] ? ' PARTITIONS ' . (+$values['partitions']) : '') |
||
549 | // ); |
||
550 | // } |
||
551 | // elseif($this->driver->support('partitioning') && |
||
552 | // \preg_match('~partitioned~', $this->tableStatus->Create_options)) |
||
553 | // { |
||
554 | // $partitioning .= "\nREMOVE PARTITIONING"; |
||
555 | // } |
||
556 | |||
557 | if (!isset($values['comment'])) { |
||
558 | $values['comment'] = ''; |
||
559 | } |
||
560 | if (!isset($values['engine']) || !$values['engine']) { |
||
561 | $values['engine'] = ''; |
||
562 | } |
||
563 | if (!isset($values['collation']) || !$values['collation']) { |
||
564 | $values['collation'] = ''; |
||
565 | } |
||
566 | |||
567 | if ($this->tableStatus != null) { |
||
568 | // if ($values['comment'] == $this->tableStatus->comment) { |
||
569 | // $values['comment'] = null; |
||
570 | // } |
||
571 | if ($values['engine'] == $this->tableStatus->engine) { |
||
572 | $values['engine'] = ''; |
||
573 | } |
||
574 | if ($values['collation'] == $this->tableStatus->collation) { |
||
575 | $values['collation'] = ''; |
||
576 | } |
||
577 | } |
||
578 | |||
579 | $name = \trim($values['name']); |
||
580 | $autoIncrement = $this->util->number($this->util->input()->getAutoIncrementStep()); |
||
581 | if ($this->driver->jush() == 'sqlite' && ($useAllFields || $foreign)) { |
||
582 | $fields = $allFields; |
||
583 | } |
||
584 | |||
585 | $success = $this->driver->alterTable($table, $name, $fields, $foreign, $values['comment'], |
||
586 | $values['engine'], $values['collation'], \intval($autoIncrement), $partitioning); |
||
587 | |||
588 | $error = $this->driver->error(); |
||
589 | |||
590 | return \compact('success', 'error'); |
||
591 | } |
||
592 | |||
593 | /** |
||
594 | * Create a table |
||
595 | * |
||
596 | * @param array $values The table values |
||
597 | * |
||
598 | * @return array |
||
599 | */ |
||
600 | public function createTable(array $values) |
||
601 | { |
||
602 | $results = $this->createOrAlterTable($values); |
||
603 | $results['message'] = $this->trans->lang('Table has been created.'); |
||
604 | return $results; |
||
605 | } |
||
606 | |||
607 | /** |
||
608 | * Alter a table |
||
609 | * |
||
610 | * @param string $table The table name |
||
611 | * @param array $values The table values |
||
612 | * |
||
613 | * @return array |
||
614 | */ |
||
615 | public function alterTable(string $table, array $values) |
||
616 | { |
||
617 | $origFields = $this->driver->fields($table); |
||
618 | $this->tableStatus = $this->driver->tableStatus($table); |
||
619 | if (!$this->tableStatus) { |
||
620 | throw new Exception($this->trans->lang('No tables.')); |
||
621 | } |
||
622 | |||
623 | $results = $this->createOrAlterTable($values, $table, $origFields); |
||
624 | $results['message'] = $this->trans->lang('Table has been altered.'); |
||
625 | return $results; |
||
626 | } |
||
627 | |||
628 | /** |
||
629 | * Drop a table |
||
630 | * |
||
631 | * @param string $table The table name |
||
632 | * |
||
633 | * @return array |
||
634 | */ |
||
635 | public function dropTable(string $table) |
||
644 | } |
||
645 | } |
||
646 |
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.