TblpropertiesController::doAlter()   C
last analyzed

Complexity

Conditions 17
Paths 34

Size

Total Lines 110
Code Lines 78

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 17
eloc 78
c 1
b 0
f 0
nc 34
nop 1
dl 0
loc 110
rs 5.2166

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/**
4
 * PHPPgAdmin 6.1.3
5
 */
6
7
namespace PHPPgAdmin\Controller;
8
9
use PHPPgAdmin\Decorators\Decorator;
10
11
/**
12
 * Base controller class.
13
 */
14
class TblpropertiesController extends BaseController
15
{
16
    use \PHPPgAdmin\Traits\ExportTrait;
0 ignored issues
show
Bug introduced by
The trait PHPPgAdmin\Traits\ExportTrait requires the property $subFolder which is not provided by PHPPgAdmin\Controller\TblpropertiesController.
Loading history...
17
18
    public $controller_title = 'strtables';
19
20
    /**
21
     * Default method to render the controller according to the action parameter.
22
     */
23
    public function render()
24
    {
25
        if ('tree' === $this->action) {
26
            return $this->doTree();
27
        }
28
29
        $header_template = 'header.twig';
30
31
        \ob_start();
32
33
        switch ($this->action) {
34
            case 'alter':
35
                if (null !== $this->getPostParam('alter')) {
36
                    $this->doSaveAlter();
37
                } else {
38
                    $this->doDefault();
39
                }
40
41
                break;
42
            case 'confirm_alter':
43
                $this->doAlter();
44
45
                break;
46
            case 'import':
47
                $this->doImport();
48
49
                break;
50
            case 'export':
51
                $this->doExport();
52
53
                break;
54
            case 'add_column':
55
                if (null !== $this->getPostParam('cancel')) {
56
                    $this->doDefault();
57
                } else {
58
                    $header_template = 'header_select2.twig';
59
                    $this->doAddColumn();
60
                }
61
62
                break;
63
                /*case 'properties':
64
                if($this->getPostParam('cancel')!==null){
65
                $this->doDefault();
66
                } else {
67
                $this->doProperties();
68
                }*/
69
70
                break;
71
            case 'drop':
72
                if (null !== $this->getPostParam('drop')) {
73
                    $this->doDrop(false);
74
                } else {
75
                    $this->doDefault();
76
                }
77
78
                break;
79
            case 'confirm_drop':
80
                $this->doDrop(true);
81
82
                break;
83
84
            default:
85
                $this->doDefault();
86
87
                break;
88
        }
89
90
        $output = \ob_get_clean();
91
92
        $this->printHeader($this->headerTitle('', '', $_REQUEST['table']), null, true, $header_template);
93
        $this->printBody();
94
95
        echo $output;
96
97
        return $this->printFooter();
98
    }
99
100
    /**
101
     * Show default list of columns in the table.
102
     *
103
     * @param mixed $msg
104
     */
105
    public function doDefault($msg = ''): void
106
    {
107
        $misc = $this->misc;
108
        $this->data = $misc->getDatabaseAccessor();
109
110
        $this->printTrail('table');
111
        $this->printTabs('table', 'columns');
112
        $this->printMsg($msg);
113
114
        // Get table
115
        $tdata = $this->data->getTable($_REQUEST['table']);
116
        // Get columns
117
        $attrs = $this->data->getTableAttributes($_REQUEST['table']);
118
        // Get constraints keys
119
        $ck = $this->data->getConstraintsWithFields($_REQUEST['table']);
120
121
        // Show comment if any
122
        if (null !== $tdata->fields['relcomment']) {
123
            echo '<p class="comment">', $misc->printVal($tdata->fields['relcomment']), '</p>' . \PHP_EOL;
124
        }
125
        $this->_printTable($ck, $attrs);
126
127
        $navlinks = [
128
            'browse' => [
129
                'attr' => [
130
                    'href' => [
131
                        'url' => 'display',
132
                        'urlvars' => [
133
                            'server' => $_REQUEST['server'],
134
                            'database' => $_REQUEST['database'],
135
                            'schema' => $_REQUEST['schema'],
136
                            'table' => $_REQUEST['table'],
137
                            'subject' => 'table',
138
                            'return' => 'table',
139
                        ],
140
                    ],
141
                ],
142
                'content' => $this->lang['strbrowse'],
143
            ],
144
            'select' => [
145
                'attr' => [
146
                    'href' => [
147
                        'url' => 'tables',
148
                        'urlvars' => [
149
                            'action' => 'confselectrows',
150
                            'server' => $_REQUEST['server'],
151
                            'database' => $_REQUEST['database'],
152
                            'schema' => $_REQUEST['schema'],
153
                            'table' => $_REQUEST['table'],
154
                        ],
155
                    ],
156
                ],
157
                'content' => $this->lang['strselect'],
158
            ],
159
            'insert' => [
160
                'attr' => [
161
                    'href' => [
162
                        'url' => 'tables',
163
                        'urlvars' => [
164
                            'action' => 'confinsertrow',
165
                            'server' => $_REQUEST['server'],
166
                            'database' => $_REQUEST['database'],
167
                            'schema' => $_REQUEST['schema'],
168
                            'table' => $_REQUEST['table'],
169
                        ],
170
                    ],
171
                ],
172
                'content' => $this->lang['strinsert'],
173
            ],
174
            'empty' => [
175
                'attr' => [
176
                    'href' => [
177
                        'url' => 'tables',
178
                        'urlvars' => [
179
                            'action' => 'confirm_empty',
180
                            'server' => $_REQUEST['server'],
181
                            'database' => $_REQUEST['database'],
182
                            'schema' => $_REQUEST['schema'],
183
                            'table' => $_REQUEST['table'],
184
                        ],
185
                    ],
186
                ],
187
                'content' => $this->lang['strempty'],
188
            ],
189
            'drop' => [
190
                'attr' => [
191
                    'href' => [
192
                        'url' => 'tables',
193
                        'urlvars' => [
194
                            'action' => 'confirm_drop',
195
                            'server' => $_REQUEST['server'],
196
                            'database' => $_REQUEST['database'],
197
                            'schema' => $_REQUEST['schema'],
198
                            'table' => $_REQUEST['table'],
199
                        ],
200
                    ],
201
                ],
202
                'content' => $this->lang['strdrop'],
203
            ],
204
            'addcolumn' => [
205
                'attr' => [
206
                    'href' => [
207
                        'url' => 'tblproperties',
208
                        'urlvars' => [
209
                            'action' => 'add_column',
210
                            'server' => $_REQUEST['server'],
211
                            'database' => $_REQUEST['database'],
212
                            'schema' => $_REQUEST['schema'],
213
                            'table' => $_REQUEST['table'],
214
                        ],
215
                    ],
216
                ],
217
                'content' => $this->lang['straddcolumn'],
218
            ],
219
            'alter' => [
220
                'attr' => [
221
                    'href' => [
222
                        'url' => 'tblproperties',
223
                        'urlvars' => [
224
                            'action' => 'confirm_alter',
225
                            'server' => $_REQUEST['server'],
226
                            'database' => $_REQUEST['database'],
227
                            'schema' => $_REQUEST['schema'],
228
                            'table' => $_REQUEST['table'],
229
                        ],
230
                    ],
231
                ],
232
                'content' => $this->lang['stralter'],
233
            ],
234
        ];
235
        $this->printNavLinks($navlinks, 'tblproperties-tblproperties', \get_defined_vars());
236
    }
237
238
    public function doTree()
239
    {
240
        $misc = $this->misc;
241
        $data = $misc->getDatabaseAccessor();
242
243
        $columns = $data->getTableAttributes($_REQUEST['table']);
244
        $reqvars = $misc->getRequestVars('column');
245
246
        $attrs = [
247
            'text' => Decorator::field('attname'),
248
            'action' => Decorator::actionurl(
249
                'colproperties',
250
                $reqvars,
251
                [
252
                    'table' => $_REQUEST['table'],
253
                    'column' => Decorator::field('attname'),
254
                ]
255
            ),
256
            'icon' => 'Column',
257
            'iconAction' => Decorator::url(
258
                'display',
259
                $reqvars,
260
                [
261
                    'table' => $_REQUEST['table'],
262
                    'column' => Decorator::field('attname'),
263
                    'query' => Decorator::replace(
264
                        'SELECT "%column%", count(*) AS "count" FROM "%table%" GROUP BY "%column%" ORDER BY "%column%"',
265
                        [
266
                            '%column%' => Decorator::field('attname'),
267
                            '%table%' => $_REQUEST['table'],
268
                        ]
269
                    ),
270
                ]
271
            ),
272
            'toolTip' => Decorator::field('comment'),
273
        ];
274
275
        return $this->printTree($columns, $attrs, 'tblcolumns');
276
    }
277
278
    public function doSaveAlter(): void
279
    {
280
        $misc = $this->misc;
281
        $data = $misc->getDatabaseAccessor();
282
283
        // For databases that don't allow owner change
284
        $this->coalesceArr($_POST, 'owner', '');
285
286
        // Default tablespace to null if it isn't set
287
        $this->coalesceArr($_POST, 'tablespace', null);
288
289
        $this->coalesceArr($_POST, 'newschema', null);
290
        $with_oids = (bool) ($this->getPostParam('with_oids', false));
291
292
        $status = $data->alterTable(
293
            $this->getPostParam('table'),
294
            $this->getPostParam('name'),
295
            $this->getPostParam('owner'),
296
            $this->getPostParam('newschema'),
297
            $this->getPostParam('comment'),
298
            $this->getPostParam('tablespace'),
299
            $with_oids
300
        );
301
302
        if (0 === $status) {
303
            // If table has been renamed, need to change to the new name and
304
            // reload the browser frame.
305
            if ($_POST['table'] !== $_POST['name']) {
306
                // Jump them to the new table name
307
                $_REQUEST['table'] = $_POST['name'];
308
                // Force a browser reload
309
                $this->view->setReloadBrowser(true);
310
            }
311
            // If schema has changed, need to change to the new schema and reload the browser
312
            if (!empty($_POST['newschema']) && ($_POST['newschema'] !== $data->_schema)) {
313
                // Jump them to the new sequence schema
314
                $misc->setCurrentSchema($_POST['newschema']);
315
                $this->view->setReloadBrowser(true);
316
            }
317
            $this->doDefault($this->lang['strtablealtered']);
318
        } else {
319
            $this->doAlter($this->lang['strtablealteredbad']);
320
        }
321
    }
322
323
    /**
324
     * Function to allow altering of a table.
325
     *
326
     * @param mixed $msg
327
     */
328
    public function doAlter($msg = ''): void
329
    {
330
        $misc = $this->misc;
331
        $data = $misc->getDatabaseAccessor();
332
333
        $this->printTrail('table');
334
        $this->printTitle($this->lang['stralter'], 'pg.table.alter');
335
        $this->printMsg($msg);
336
337
        // Fetch table info
338
        $table = $data->getTable($_REQUEST['table']);
339
        // Fetch all users
340
        $users = $data->getUsers();
341
        $tablespaces = null;
342
        // Fetch all tablespaces from the database
343
        if ($data->hasTablespaces()) {
344
            $tablespaces = $data->getTablespaces(true);
345
        }
346
347
        if (0 < $table->recordCount()) {
348
            $this->coalesceArr($_POST, 'name', $table->fields['relname']);
349
350
            $this->coalesceArr($_POST, 'owner', $table->fields['relowner']);
351
352
            $this->coalesceArr($_POST, 'newschema', $table->fields['nspname']);
353
354
            $this->coalesceArr($_POST, 'comment', $table->fields['relcomment']);
355
356
            if ($data->hasTablespaces() && !isset($_POST['tablespace'])) {
357
                $_POST['tablespace'] = $table->fields['tablespace'];
358
            }
359
360
            echo '<form action="' . \containerInstance()->subFolder . '/src/views/tblproperties" method="post">' . \PHP_EOL;
361
            echo '<table>' . \PHP_EOL;
362
            echo "<tr><th class=\"data left required\">{$this->lang['strname']}</th>" . \PHP_EOL;
363
            echo '<td class="data1">';
364
            echo "<input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"",
365
                \htmlspecialchars($_POST['name'], \ENT_QUOTES),
366
                '" /></td></tr>' . \PHP_EOL;
367
368
            if ($data->isSuperUser()) {
369
                echo "<tr><th class=\"data left required\">{$this->lang['strowner']}</th>" . \PHP_EOL;
370
                echo '<td class="data1"><select name="owner">';
371
372
                while (!$users->EOF) {
373
                    $uname = $users->fields['usename'];
374
                    echo '<option value="', \htmlspecialchars($uname), '"',
375
                        ($uname === $_POST['owner']) ? ' selected="selected"' : '',
376
                        '>',
377
                        \htmlspecialchars($uname),
378
                        '</option>' . \PHP_EOL;
379
                    $users->moveNext();
380
                }
381
                echo '</select></td></tr>' . \PHP_EOL;
382
            }
383
384
            if ($data->hasAlterTableSchema()) {
385
                $schemas = $data->getSchemas();
386
                echo "<tr><th class=\"data left required\">{$this->lang['strschema']}</th>" . \PHP_EOL;
387
                echo '<td class="data1"><select name="newschema">';
388
389
                while (!$schemas->EOF) {
390
                    $schema = $schemas->fields['nspname'];
391
                    echo '<option value="', \htmlspecialchars($schema), '"',
392
                        ($schema === $_POST['newschema']) ? ' selected="selected"' : '',
393
                        '>',
394
                        \htmlspecialchars($schema),
395
                        '</option>' . \PHP_EOL;
396
                    $schemas->moveNext();
397
                }
398
                echo '</select></td></tr>' . \PHP_EOL;
399
            }
400
401
            // Tablespace (if there are any)
402
            if ($data->hasTablespaces() && 0 < $tablespaces->recordCount()) {
403
                echo "\t<tr>\n\t\t<th class=\"data left\">{$this->lang['strtablespace']}</th>" . \PHP_EOL;
404
                echo "\t\t<td class=\"data1\">\n\t\t\t<select name=\"tablespace\">" . \PHP_EOL;
405
                // Always offer the default (empty) option
406
                echo "\t\t\t\t<option value=\"\"",
407
                    ('' === $_POST['tablespace']) ? ' selected="selected"' : '',
408
                    '></option>' . \PHP_EOL;
409
                // Display all other tablespaces
410
                while (!$tablespaces->EOF) {
411
                    $spcname = \htmlspecialchars($tablespaces->fields['spcname']);
412
                    echo "\t\t\t\t<option value=\"{$spcname}\"",
413
                        ($spcname === $_POST['tablespace']) ? ' selected="selected"' : '',
414
                        ">{$spcname}</option>" . \PHP_EOL;
415
                    $tablespaces->moveNext();
416
                }
417
                echo "\t\t\t</select>\n\t\t</td>\n\t</tr>" . \PHP_EOL;
418
            }
419
            echo '<tr><th class="data left"> </th>' . \PHP_EOL;
420
            echo '<td class="data1">';
421
            echo \sprintf('<input type="checkbox" name="with_oids" value="1" %s /> %s', $data->hasObjectID($table->fields['relname']) ? 'checked' : '', ' WITH OIDS');
422
423
            echo '</td></tr>';
424
425
            echo "<tr><th class=\"data left\">{$this->lang['strcomment']}</th>" . \PHP_EOL;
426
            echo '<td class="data1">';
427
            echo \sprintf('<textarea rows="3" cols="62" name="comment">%s</textarea>', \htmlspecialchars($_POST['comment']));
428
            echo \sprintf('</td></tr>%s</table>%s', \PHP_EOL, \PHP_EOL);
429
            echo '<p><input type="hidden" name="action" value="alter" />' . \PHP_EOL;
430
            echo \sprintf('<input type="hidden" name="table" value="%s"  />%s', \htmlspecialchars($_REQUEST['table']), \PHP_EOL);
431
432
            echo $this->view->form;
433
            echo "<input type=\"submit\" name=\"alter\" value=\"{$this->lang['stralter']}\" />" . \PHP_EOL;
434
            echo \sprintf('<input type="submit" name="cancel" value="%s"  /></p>%s', $this->lang['strcancel'], \PHP_EOL);
435
            echo '</form>' . \PHP_EOL;
436
        } else {
437
            echo "<p>{$this->lang['strnodata']}</p>" . \PHP_EOL;
438
        }
439
    }
440
441
    public function doExport($msg = ''): void
442
    {
443
        $data = $this->misc->getDatabaseAccessor();
444
        $subject = 'table';
445
        $object = $_REQUEST['table'];
446
        // Determine whether or not the table has an object ID
447
        $hasID = $data->hasObjectID($object);
448
        $this->printTrail('table');
449
        $this->printTabs('table', 'export');
450
        $this->printMsg($msg);
451
452
        echo $this->formHeader();
453
454
        // Data only
455
        echo $this->dataOnly($hasID);
456
457
        // Structure only
458
        echo $this->structureOnly();
459
        // Structure and data
460
        echo $this->structureAndData($hasID);
461
462
        echo $this->displayOrDownload();
463
464
        echo $this->formFooter($subject, $object);
465
    }
466
467
    public function doImport($msg = ''): void
468
    {
469
        $misc = $this->misc;
470
471
        $this->printTrail('table');
472
        $this->printTabs('table', 'import');
473
        $this->printMsg($msg);
474
475
        // Check that file uploads are enabled
476
        if (!\ini_get('file_uploads')) {
477
            echo "<p>{$this->lang['strnouploads']}</p>" . \PHP_EOL;
478
479
            return;
480
        }
481
        // Don't show upload option if max size of uploads is zero
482
        $max_size = $misc->inisizeToBytes(\ini_get('upload_max_filesize'));
483
484
        if (\is_float($max_size) && 0 < $max_size) {
485
            echo '<form action="' . \containerInstance()->subFolder . '/src/views/dataimport" method="post" enctype="multipart/form-data">' . \PHP_EOL;
486
            echo '<table>' . \PHP_EOL;
487
            echo "\t<tr>\n\t\t<th class=\"data left required\">{$this->lang['strformat']}</th>" . \PHP_EOL;
488
            echo "\t\t<td><select name=\"format\">" . \PHP_EOL;
489
            echo "\t\t\t<option value=\"auto\">{$this->lang['strauto']}</option>" . \PHP_EOL;
490
            echo "\t\t\t<option value=\"csv\">CSV</option>" . \PHP_EOL;
491
            echo "\t\t\t<option value=\"tab\">{$this->lang['strtabbed']}</option>" . \PHP_EOL;
492
493
            if (\function_exists('xml_parser_create')) {
494
                echo "\t\t\t<option value=\"xml\">XML</option>" . \PHP_EOL;
495
            }
496
            echo "\t\t</select></td>\n\t</tr>" . \PHP_EOL;
497
            echo "\t<tr>\n\t\t<th class=\"data left required\">{$this->lang['strallowednulls']}</th>" . \PHP_EOL;
498
            echo "\t\t<td><label><input type=\"checkbox\" name=\"allowednulls[0]\" value=\"\\N\" checked=\"checked\" />{$this->lang['strbackslashn']}</label><br />" . \PHP_EOL;
499
            echo "\t\t<label><input type=\"checkbox\" name=\"allowednulls[1]\" value=\"NULL\" />NULL</label><br />" . \PHP_EOL;
500
            echo "\t\t<label><input type=\"checkbox\" name=\"allowednulls[2]\" value=\"\" />{$this->lang['stremptystring']}</label></td>\n\t</tr>" . \PHP_EOL;
501
            echo "\t<tr>\n\t\t<th class=\"data left required\">{$this->lang['strfile']}</th>" . \PHP_EOL;
502
            echo "\t\t<td><input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"{$max_size}\" />";
503
            echo "<input type=\"file\" name=\"source\" /></td>\n\t</tr>" . \PHP_EOL;
504
            echo '</table>' . \PHP_EOL;
505
            echo '<p><input type="hidden" name="action" value="import" />' . \PHP_EOL;
506
            echo $this->view->form;
507
            echo \sprintf('<input type="hidden" name="table" value="%s"  />%s', \htmlspecialchars($_REQUEST['table']), \PHP_EOL);
508
            echo "<input type=\"submit\" value=\"{$this->lang['strimport']}\" /></p>" . \PHP_EOL;
509
            echo '</form>' . \PHP_EOL;
510
        }
511
    }
512
513
    /**
514
     * Displays a screen where they can add a column.
515
     *
516
     * @param mixed $msg
517
     */
518
    public function doAddColumn($msg = ''): void
519
    {
520
        $misc = $this->misc;
521
        $data = $misc->getDatabaseAccessor();
522
523
        $this->coalesceArr($_REQUEST, 'stage', 1);
524
525
        switch ($_REQUEST['stage']) {
526
            case 1:
527
                // Set variable defaults
528
                $this->coalesceArr($_POST, 'field', '');
529
530
                $this->coalesceArr($_POST, 'type', '');
531
532
                $this->coalesceArr($_POST, 'array', '');
533
534
                $this->coalesceArr($_POST, 'length', '');
535
536
                $this->coalesceArr($_POST, 'default', '');
537
538
                $this->coalesceArr($_POST, 'comment', '');
539
540
                // Fetch all available types
541
                $types = $data->getTypes(true, false, true);
542
                $types_for_js = [];
543
544
                $this->printTrail('table');
545
                $this->printTitle($this->lang['straddcolumn'], 'pg.column.add');
546
                $this->printMsg($msg);
547
548
                echo '<script src="' . \containerInstance()->subFolder . '/assets/js/tables.js" type="text/javascript"></script>';
549
                echo '<form action="' . \containerInstance()->subFolder . '/src/views/tblproperties" method="post">' . \PHP_EOL;
550
551
                // Output table header
552
                echo '<table>' . \PHP_EOL;
553
                echo "<tr><th class=\"data required\">{$this->lang['strname']}</th>\n<th colspan=\"2\" class=\"data required\">{$this->lang['strtype']}</th>" . \PHP_EOL;
554
                echo "<th class=\"data\">{$this->lang['strlength']}</th>" . \PHP_EOL;
555
556
                if ($data->hasCreateFieldWithConstraints()) {
557
                    echo "<th class=\"data\">{$this->lang['strnotnull']}</th>\n<th class=\"data\">{$this->lang['strdefault']}</th>" . \PHP_EOL;
558
                }
559
560
                echo "<th class=\"data\">{$this->lang['strcomment']}</th></tr>" . \PHP_EOL;
561
562
                echo "<tr><td><input name=\"field\" size=\"16\" maxlength=\"{$data->_maxNameLen}\" value=\"",
563
                    \htmlspecialchars($_POST['field']),
564
                    '" /></td>' . \PHP_EOL;
565
                echo "<td><select  class=\"select2\" name=\"type\" id=\"type\" onchange=\"checkLengths(document.getElementById('type').value,'');\">" . \PHP_EOL;
566
                // Output any "magic" types.  This came in with the alter column type so we'll check that
567
                if ($data->hasMagicTypes()) {
568
                    foreach ($data->extraTypes as $v) {
569
                        $types_for_js[] = \mb_strtolower($v);
570
                        echo "\t<option value=\"", \htmlspecialchars($v), '"',
571
                            ($v === $_POST['type']) ? ' selected="selected"' : '',
572
                            '>',
573
                            $misc->printVal($v),
574
                            '</option>' . \PHP_EOL;
575
                    }
576
                }
577
578
                while (!$types->EOF) {
579
                    $typname = $types->fields['typname'];
580
                    $types_for_js[] = $typname;
581
                    echo "\t<option value=\"", \htmlspecialchars($typname), '"', ($typname === $_POST['type']) ? ' selected="selected"' : '', '>',
582
                        $misc->printVal($typname),
583
                        '</option>' . \PHP_EOL;
584
                    $types->moveNext();
585
                }
586
                echo '</select></td>' . \PHP_EOL;
587
588
                // Output array type selector
589
                echo '<td><select name="array">' . \PHP_EOL;
590
                echo "\t<option value=\"\"", ('' === $_POST['array']) ? ' selected="selected"' : '', '></option>' . \PHP_EOL;
591
                echo "\t<option value=\"[]\"", ('[]' === $_POST['array']) ? ' selected="selected"' : '', '>[ ]</option>' . \PHP_EOL;
592
                echo '</select></td>' . \PHP_EOL;
593
                $predefined_size_types = \array_intersect($data->predefined_size_types, $types_for_js);
594
                $escaped_predef_types = []; // the JS escaped array elements
595
596
                foreach ($predefined_size_types as $value) {
597
                    $escaped_predef_types[] = "'{$value}'";
598
                }
599
600
                echo '<td><input name="length" id="lengths" size="8" value="',
601
                    \htmlspecialchars($_POST['length']),
602
                    '" /></td>' . \PHP_EOL;
603
                // Support for adding column with not null and default
604
                if ($data->hasCreateFieldWithConstraints()) {
605
                    echo '<td><input type="checkbox" name="notnull"',
606
                        (isset($_REQUEST['notnull'])) ? ' checked="checked"' : '',
607
                        ' /></td>' . \PHP_EOL;
608
                    echo '<td><input name="default" size="20" value="',
609
                        \htmlspecialchars($_POST['default']),
610
                        '" /></td>' . \PHP_EOL;
611
                }
612
                echo '<td><input name="comment" size="40" value="',
613
                    \htmlspecialchars($_POST['comment']),
614
                    '" /></td></tr>' . \PHP_EOL;
615
                echo '</table>' . \PHP_EOL;
616
                echo '<p><input type="hidden" name="action" value="add_column" />' . \PHP_EOL;
617
                echo '<input type="hidden" name="stage" value="2" />' . \PHP_EOL;
618
                echo $this->view->form;
619
                echo \sprintf('<input type="hidden" name="table" value="%s"  />%s', \htmlspecialchars($_REQUEST['table']), \PHP_EOL);
620
621
                if (!$data->hasCreateFieldWithConstraints()) {
622
                    echo '<input type="hidden" name="default" value="" />' . \PHP_EOL;
623
                }
624
                echo "<input type=\"submit\" value=\"{$this->lang['stradd']}\" />" . \PHP_EOL;
625
                echo \sprintf('<input type="submit" name="cancel" value="%s"  /></p>%s', $this->lang['strcancel'], \PHP_EOL);
626
                echo '</form>' . \PHP_EOL;
627
                echo '<script type="text/javascript">predefined_lengths = new Array(' . \implode(',', $escaped_predef_types) . ");checkLengths(document.getElementById('type').value,'');</script>" . \PHP_EOL;
0 ignored issues
show
Coding Style introduced by
This line exceeds maximum limit of 190 characters; contains 207 characters

Overly long lines are hard to read on any screen. Most code styles therefor impose a maximum limit on the number of characters in a line.

Loading history...
628
629
                break;
630
            case 2:
631
                // Check inputs
632
                if ('' === \trim($_POST['field'])) {
633
                    $_REQUEST['stage'] = 1;
634
                    $this->doAddColumn($this->lang['strcolneedsname']);
635
636
                    return;
637
                }
638
                $this->coalesceArr($_POST, 'length', '');
639
640
                [$status, $sql] = $data->addColumn(
641
                    $_POST['table'],
642
                    $_POST['field'],
643
                    $_POST['type'],
644
                    '' !== $_POST['array'],
645
                    $_POST['length'],
646
                    isset($_POST['notnull']),
647
                    $_POST['default'],
648
                    $_POST['comment']
649
                );
650
651
                if (0 === $status) {
652
                    $this->view->setReloadBrowser(true);
653
                    $this->doDefault(\sprintf('%s %s %s', $sql, \PHP_EOL, $this->lang['strcolumnadded']));
654
                } else {
655
                    $_REQUEST['stage'] = 1;
656
                    $this->doAddColumn($this->lang['strcolumnaddedbad']);
657
658
                    return;
659
                }
660
661
                break;
662
663
            default:
664
                echo "<p>{$this->lang['strinvalidparam']}</p>" . \PHP_EOL;
665
        }
666
    }
667
668
    /**
669
     * Show confirmation of drop column and perform actual drop.
670
     *
671
     * @param bool $confirm true to ask for confirmation, false to actually drop
672
     */
673
    public function doDrop($confirm = true): void
674
    {
675
        $misc = $this->misc;
676
        $data = $misc->getDatabaseAccessor();
677
678
        if ($confirm) {
679
            $this->printTrail('column');
680
            $this->printTitle($this->lang['strdrop'], 'pg.column.drop');
681
682
            echo '<p>' . \sprintf($this->lang['strconfdropcolumn'], $misc->printVal($_REQUEST['column']), $misc->printVal($_REQUEST['table'])) . '</p>' . \PHP_EOL;
683
684
            echo '<form action="' . \containerInstance()->subFolder . '/src/views/tblproperties" method="post">' . \PHP_EOL;
685
            echo '<input type="hidden" name="action" value="drop" />' . \PHP_EOL;
686
            echo \sprintf('<input type="hidden" name="table" value="%s"  />%s', \htmlspecialchars($_REQUEST['table']), \PHP_EOL);
687
            echo '<input type="hidden" name="column" value="', \htmlspecialchars($_REQUEST['column']), '" />' . \PHP_EOL;
688
            echo $this->view->form;
689
            echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\"> <label for=\"cascade\">{$this->lang['strcascade']}</label></p>" . \PHP_EOL;
690
            echo "<input type=\"submit\" name=\"drop\" value=\"{$this->lang['strdrop']}\" />" . \PHP_EOL;
691
            echo "<input type=\"submit\" name=\"cancel\" value=\"{$this->lang['strcancel']}\" />" . \PHP_EOL;
692
            echo '</form>' . \PHP_EOL;
693
        } else {
694
            [$status, $sql] = $data->dropColumn($_POST['table'], $_POST['column'], isset($_POST['cascade']));
695
696
            if (0 === $status) {
697
                $this->view->setReloadBrowser(true);
698
                $this->doDefault(\sprintf('%s %s %s', $sql, \PHP_EOL, $this->lang['strcolumndropped']));
699
            } else {
700
                $this->doDefault($this->lang['strcolumndroppedbad']);
701
            }
702
        }
703
    }
704
705
    private function _getAttPre($data)
706
    {
707
        $attPre = static function (&$rowdata, $actions) use ($data) {
708
            $rowdata->fields['+type'] = $data->formatType($rowdata->fields['type'], $rowdata->fields['atttypmod']);
709
            $attname = $rowdata->fields['attname'];
710
            $table = $_REQUEST['table'];
711
            $data->fieldClean($attname);
712
            $data->fieldClean($table);
713
714
            $actions['browse']['attr']['href']['urlvars']['query'] = "SELECT \"{$attname}\", count(*) AS \"count\"
715
                FROM \"{$table}\" GROUP BY \"{$attname}\" ORDER BY \"{$attname}\"";
716
717
            return $actions;
718
        };
719
720
        return $attPre;
721
    }
722
723
    private function _getCstrRender($misc, $data)
724
    {
725
        $view = $this->view;
726
        $cstrRender = static function ($s, $p) use ($misc, $data, $view) {
727
            $str = '';
728
729
            foreach ($p['keys'] as $k => $c) {
730
                if (null === $p['keys'][$k]['consrc']) {
731
                    $atts = $data->getAttributeNames($_REQUEST['table'], \explode(' ', $p['keys'][$k]['indkey']));
732
                    $c['consrc'] = ('u' === $c['contype'] ? 'UNIQUE (' : 'PRIMARY KEY (') . \implode(',', $atts) . ')';
733
                }
734
                $consrc = \htmlentities($c['consrc'], \ENT_QUOTES, 'UTF-8');
735
                $table_key = 'p_table';
736
                $schema_key = 'p_schema';
737
738
                if ($c['p_field'] !== $s) {
739
                    continue;
740
                }
741
742
                switch ($c['contype']) {
743
                    case 'p':
744
                        $type = 'pk';
745
746
                        $icon = 'PrimaryKey';
747
748
                        break;
749
                    case 'f':
750
                        $table_key = 'f_table';
751
                        $icon = 'ForeignKey';
752
                        $schema_key = 'f_schema';
753
                        $type = 'fk';
754
755
                        break;
756
                    case 'u':
757
                        $type = 'uniq';
758
759
                        $icon = 'UniqueConstraint';
760
761
                        break;
762
                    case 'c':
763
                        $type = 'check';
764
765
                        $icon = 'CheckConstraint';
766
                }
767
                $str .= \sprintf(
768
                    '<a href="tblproperties?%s&amp;table=%s&amp;schema=%s">',
769
                    $misc->href,
770
                    \urlencode($c[$table_key]),
771
                    \urlencode($c[$schema_key])
772
                );
773
774
                $str .= \sprintf(
775
                    '
776
                    <img src="%s" alt="[%s]" title="%s" /></a>',
777
                    $view->icon($icon),
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $icon does not seem to be defined for all execution paths leading up to this point.
Loading history...
778
                    $type,
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $type does not seem to be defined for all execution paths leading up to this point.
Loading history...
779
                    $consrc
780
                );
781
            }
782
783
            return $str;
784
        };
785
786
        return $cstrRender;
787
    }
788
789
    private function _printTable($ck, $attrs): void
790
    {
791
        $misc = $this->misc;
792
793
        $data = $this->data;
794
795
        $attPre = $this->_getAttPre($data);
796
797
        $cstrRender = $this->_getCstrRender($misc, $data);
798
799
        $columns = [
800
            'column' => [
801
                'title' => $this->lang['strcolumn'],
802
                'field' => Decorator::field('attname'),
803
                'url' => "colproperties?subject=column&amp;{$misc->href}&amp;table=" . \urlencode($_REQUEST['table']) . '&amp;',
804
                'vars' => ['column' => 'attname'],
805
            ],
806
            'type' => [
807
                'title' => $this->lang['strtype'],
808
                'field' => Decorator::field('+type'),
809
            ],
810
            'notnull' => [
811
                'title' => $this->lang['strnotnull'],
812
                'field' => Decorator::field('attnotnull'),
813
                'type' => 'bool',
814
                'params' => ['true' => 'NOT NULL', 'false' => ''],
815
            ],
816
            'default' => [
817
                'title' => $this->lang['strdefault'],
818
                'field' => Decorator::field('adsrc'),
819
            ],
820
            'keyprop' => [
821
                'title' => $this->lang['strconstraints'],
822
                'class' => 'constraint_cell',
823
                'field' => Decorator::field('attname'),
824
                'type' => 'callback',
825
                'params' => [
826
                    'function' => $cstrRender,
827
                    'keys' => $ck->getArray(),
828
                ],
829
            ],
830
            'actions' => [
831
                'title' => $this->lang['stractions'],
832
            ],
833
            'comment' => [
834
                'title' => $this->lang['strcomment'],
835
                'field' => Decorator::field('comment'),
836
            ],
837
        ];
838
839
        $actions = [
840
            'browse' => [
841
                'content' => $this->lang['strbrowse'],
842
                'attr' => [
843
                    'href' => [
844
                        'url' => 'display',
845
                        'urlvars' => [
846
                            'table' => $_REQUEST['table'],
847
                            'subject' => 'column',
848
                            'return' => 'table',
849
                            'column' => Decorator::field('attname'),
850
                        ],
851
                    ],
852
                ],
853
            ],
854
            'alter' => [
855
                'content' => $this->lang['stralter'],
856
                'attr' => [
857
                    'href' => [
858
                        'url' => 'colproperties',
859
                        'urlvars' => [
860
                            'subject' => 'column',
861
                            'action' => 'properties',
862
                            'table' => $_REQUEST['table'],
863
                            'column' => Decorator::field('attname'),
864
                        ],
865
                    ],
866
                ],
867
            ],
868
            'privileges' => [
869
                'content' => $this->lang['strprivileges'],
870
                'attr' => [
871
                    'href' => [
872
                        'url' => 'privileges',
873
                        'urlvars' => [
874
                            'subject' => 'column',
875
                            'table' => $_REQUEST['table'],
876
                            'column' => Decorator::field('attname'),
877
                        ],
878
                    ],
879
                ],
880
            ],
881
            'drop' => [
882
                'content' => $this->lang['strdrop'],
883
                'attr' => [
884
                    'href' => [
885
                        'url' => 'tblproperties',
886
                        'urlvars' => [
887
                            'subject' => 'column',
888
                            'action' => 'confirm_drop',
889
                            'table' => $_REQUEST['table'],
890
                            'column' => Decorator::field('attname'),
891
                        ],
892
                    ],
893
                ],
894
            ],
895
        ];
896
897
        echo $this->printTable($attrs, $columns, $actions, 'tblproperties-tblproperties', $this->lang['strnodata'], $attPre);
898
    }
899
}
900