Passed
Push — develop ( c2019a...2cab77 )
by Felipe
04:50
created

TblpropertiesController   F

Complexity

Total Complexity 70

Size/Duplication

Total Lines 788
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 70
dl 0
loc 788
rs 2.1818
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
B doTree() 0 38 1
D doDefault() 0 278 10
C render() 0 73 12
B doSaveAlter() 0 32 5
B doExport() 0 25 1
B doDrop() 0 27 3
B doImport() 0 40 5
D doAlter() 0 94 16
D doAddColumn() 0 133 17

How to fix   Complexity   

Complex Class

Complex classes like TblpropertiesController 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 TblpropertiesController, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * PHPPgAdmin v6.0.0-beta.48
5
 */
6
7
namespace PHPPgAdmin\Controller;
8
9
use PHPPgAdmin\Decorators\Decorator;
10
11
/**
12
 * Base controller class.
13
 *
14
 * @package PHPPgAdmin
15
 */
16
class TblpropertiesController extends BaseController
17
{
18
    use \PHPPgAdmin\Traits\ExportTrait;
19
    public $controller_title = 'strtables';
20
21
    /**
22
     * Default method to render the controller according to the action parameter.
23
     */
24
    public function render()
25
    {
26
        if ('tree' == $this->action) {
27
            return $this->doTree();
28
        }
29
30
        $header_template = 'header.twig';
31
32
        ob_start();
33
        switch ($this->action) {
34
            case 'alter':
35
                if (isset($_POST['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 (isset($_POST['cancel'])) {
56
                    $this->doDefault();
57
                } else {
58
                    $header_template = 'header_select2.twig';
59
                    $this->doAddColumn();
60
                }
61
62
                break;
63
                /*case 'properties':
64
                if (isset($_POST['cancel'])) {
65
                $this->doDefault();
66
                } else {
67
                $this->doProperties();
68
                }*/
69
70
                break;
71
            case 'drop':
72
                if (isset($_POST['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
            default:
84
                $this->doDefault();
85
86
                break;
87
        }
88
89
        $output = ob_get_clean();
90
91
        $this->printHeader($this->headerTitle('', '', $_REQUEST['table']), null, true, $header_template);
92
        $this->printBody();
93
94
        echo $output;
95
96
        return $this->printFooter();
97
    }
98
99
    /**
100
     * Show default list of columns in the table.
101
     *
102
     * @param mixed $msg
103
     */
104
    public function doDefault($msg = '')
105
    {
106
        $misc = $this->misc;
107
        $data = $misc->getDatabaseAccessor();
108
109
        $attPre = function (&$rowdata, $actions) use ($data) {
110
            $rowdata->fields['+type'] = $data->formatType($rowdata->fields['type'], $rowdata->fields['atttypmod']);
111
            $attname                  = $rowdata->fields['attname'];
112
            $table                    = $_REQUEST['table'];
113
            $data->fieldClean($attname);
114
            $data->fieldClean($table);
115
116
            $actions['browse']['attr']['href']['urlvars']['query'] = "SELECT \"{$attname}\", count(*) AS \"count\"
117
                FROM \"{$table}\" GROUP BY \"{$attname}\" ORDER BY \"{$attname}\"";
118
119
            return $actions;
120
        };
121
122
        $cstrRender = function ($s, $p) use ($misc, $data) {
123
            $str = '';
124
            foreach ($p['keys'] as $k => $c) {
125
                if (is_null($p['keys'][$k]['consrc'])) {
126
                    $atts        = $data->getAttributeNames($_REQUEST['table'], explode(' ', $p['keys'][$k]['indkey']));
127
                    $c['consrc'] = ('u' == $c['contype'] ? 'UNIQUE (' : 'PRIMARY KEY (').join(',', $atts).')';
128
                }
129
130
                if ($c['p_field'] == $s) {
131
                    switch ($c['contype']) {
132
                        case 'p':
133
                            $str .= '<a href="constraints?'.$misc->href.'&amp;table='.urlencode($c['p_table']).'&amp;schema='.urlencode($c['p_schema']).'"><img src="'.
134
                            $misc->icon('PrimaryKey').'" alt="[pk]" title="'.htmlentities($c['consrc'], ENT_QUOTES, 'UTF-8').'" /></a>';
135
136
                            break;
137
                        case 'f':
138
                            $str .= '<a href="tblproperties?'.$misc->href.'&amp;table='.urlencode($c['f_table']).'&amp;schema='.urlencode($c['f_schema']).'"><img src="'.
139
                            $misc->icon('ForeignKey').'" alt="[fk]" title="'.htmlentities($c['consrc'], ENT_QUOTES, 'UTF-8').'" /></a>';
140
141
                            break;
142
                        case 'u':
143
                            $str .= '<a href="constraints?'.$misc->href.'&amp;table='.urlencode($c['p_table']).'&amp;schema='.urlencode($c['p_schema']).'"><img src="'.
144
                            $misc->icon('UniqueConstraint').'" alt="[uniq]" title="'.htmlentities($c['consrc'], ENT_QUOTES, 'UTF-8').'" /></a>';
145
146
                            break;
147
                        case 'c':
148
                            $str .= '<a href="constraints?'.$misc->href.'&amp;table='.urlencode($c['p_table']).'&amp;schema='.urlencode($c['p_schema']).'"><img src="'.
149
                            $misc->icon('CheckConstraint').'" alt="[check]" title="'.htmlentities($c['consrc'], ENT_QUOTES, 'UTF-8').'" /></a>';
150
                    }
151
                }
152
            }
153
154
            return $str;
155
        };
156
157
        $this->printTrail('table');
158
        $this->printTabs('table', 'columns');
159
        $this->printMsg($msg);
160
161
        // Get table
162
        $tdata = $data->getTable($_REQUEST['table']);
163
        // Get columns
164
        $attrs = $data->getTableAttributes($_REQUEST['table']);
165
        // Get constraints keys
166
        $ck = $data->getConstraintsWithFields($_REQUEST['table']);
167
168
        // Show comment if any
169
        if (null !== $tdata->fields['relcomment']) {
170
            echo '<p class="comment">', $misc->printVal($tdata->fields['relcomment']), '</p>'.PHP_EOL;
171
        }
172
173
        $columns = [
174
            'column'  => [
175
                'title' => $this->lang['strcolumn'],
176
                'field' => Decorator::field('attname'),
177
                'url'   => "colproperties?subject=column&amp;{$misc->href}&amp;table=".urlencode($_REQUEST['table']).'&amp;',
178
                'vars'  => ['column' => 'attname'],
179
            ],
180
            'type'    => [
181
                'title' => $this->lang['strtype'],
182
                'field' => Decorator::field('+type'),
183
            ],
184
            'notnull' => [
185
                'title'  => $this->lang['strnotnull'],
186
                'field'  => Decorator::field('attnotnull'),
187
                'type'   => 'bool',
188
                'params' => ['true' => 'NOT NULL', 'false' => ''],
189
            ],
190
            'default' => [
191
                'title' => $this->lang['strdefault'],
192
                'field' => Decorator::field('adsrc'),
193
            ],
194
            'keyprop' => [
195
                'title'  => $this->lang['strconstraints'],
196
                'class'  => 'constraint_cell',
197
                'field'  => Decorator::field('attname'),
198
                'type'   => 'callback',
199
                'params' => [
200
                    'function' => $cstrRender,
201
                    'keys'     => $ck->getArray(),
202
                ],
203
            ],
204
            'actions' => [
205
                'title' => $this->lang['stractions'],
206
            ],
207
            'comment' => [
208
                'title' => $this->lang['strcomment'],
209
                'field' => Decorator::field('comment'),
210
            ],
211
        ];
212
213
        $actions = [
214
            'browse'     => [
215
                'content' => $this->lang['strbrowse'],
216
                'attr'    => [
217
                    'href' => [
218
                        'url'     => 'display',
219
                        'urlvars' => [
220
                            'table'   => $_REQUEST['table'],
221
                            'subject' => 'column',
222
                            'return'  => 'table',
223
                            'column'  => Decorator::field('attname'),
224
                        ],
225
                    ],
226
                ],
227
            ],
228
            'alter'      => [
229
                'content' => $this->lang['stralter'],
230
                'attr'    => [
231
                    'href' => [
232
                        'url'     => 'colproperties',
233
                        'urlvars' => [
234
                            'subject' => 'column',
235
                            'action'  => 'properties',
236
                            'table'   => $_REQUEST['table'],
237
                            'column'  => Decorator::field('attname'),
238
                        ],
239
                    ],
240
                ],
241
            ],
242
            'privileges' => [
243
                'content' => $this->lang['strprivileges'],
244
                'attr'    => [
245
                    'href' => [
246
                        'url'     => 'privileges',
247
                        'urlvars' => [
248
                            'subject' => 'column',
249
                            'table'   => $_REQUEST['table'],
250
                            'column'  => Decorator::field('attname'),
251
                        ],
252
                    ],
253
                ],
254
            ],
255
            'drop'       => [
256
                'content' => $this->lang['strdrop'],
257
                'attr'    => [
258
                    'href' => [
259
                        'url'     => 'tblproperties',
260
                        'urlvars' => [
261
                            'subject' => 'column',
262
                            'action'  => 'confirm_drop',
263
                            'table'   => $_REQUEST['table'],
264
                            'column'  => Decorator::field('attname'),
265
                        ],
266
                    ],
267
                ],
268
            ],
269
        ];
270
271
        echo $this->printTable($attrs, $columns, $actions, 'tblproperties-tblproperties', $this->lang['strnodata'], $attPre);
272
273
        $navlinks = [
274
            'browse'    => [
275
                'attr'    => [
276
                    'href' => [
277
                        'url'     => 'display',
278
                        'urlvars' => [
279
                            'server'   => $_REQUEST['server'],
280
                            'database' => $_REQUEST['database'],
281
                            'schema'   => $_REQUEST['schema'],
282
                            'table'    => $_REQUEST['table'],
283
                            'subject'  => 'table',
284
                            'return'   => 'table',
285
                        ],
286
                    ],
287
                ],
288
                'content' => $this->lang['strbrowse'],
289
            ],
290
            'select'    => [
291
                'attr'    => [
292
                    'href' => [
293
                        'url'     => 'tables',
294
                        'urlvars' => [
295
                            'action'   => 'confselectrows',
296
                            'server'   => $_REQUEST['server'],
297
                            'database' => $_REQUEST['database'],
298
                            'schema'   => $_REQUEST['schema'],
299
                            'table'    => $_REQUEST['table'],
300
                        ],
301
                    ],
302
                ],
303
                'content' => $this->lang['strselect'],
304
            ],
305
            'insert'    => [
306
                'attr'    => [
307
                    'href' => [
308
                        'url'     => 'tables',
309
                        'urlvars' => [
310
                            'action'   => 'confinsertrow',
311
                            'server'   => $_REQUEST['server'],
312
                            'database' => $_REQUEST['database'],
313
                            'schema'   => $_REQUEST['schema'],
314
                            'table'    => $_REQUEST['table'],
315
                        ],
316
                    ],
317
                ],
318
                'content' => $this->lang['strinsert'],
319
            ],
320
            'empty'     => [
321
                'attr'    => [
322
                    'href' => [
323
                        'url'     => 'tables',
324
                        'urlvars' => [
325
                            'action'   => 'confirm_empty',
326
                            'server'   => $_REQUEST['server'],
327
                            'database' => $_REQUEST['database'],
328
                            'schema'   => $_REQUEST['schema'],
329
                            'table'    => $_REQUEST['table'],
330
                        ],
331
                    ],
332
                ],
333
                'content' => $this->lang['strempty'],
334
            ],
335
            'drop'      => [
336
                'attr'    => [
337
                    'href' => [
338
                        'url'     => 'tables',
339
                        'urlvars' => [
340
                            'action'   => 'confirm_drop',
341
                            'server'   => $_REQUEST['server'],
342
                            'database' => $_REQUEST['database'],
343
                            'schema'   => $_REQUEST['schema'],
344
                            'table'    => $_REQUEST['table'],
345
                        ],
346
                    ],
347
                ],
348
                'content' => $this->lang['strdrop'],
349
            ],
350
            'addcolumn' => [
351
                'attr'    => [
352
                    'href' => [
353
                        'url'     => 'tblproperties',
354
                        'urlvars' => [
355
                            'action'   => 'add_column',
356
                            'server'   => $_REQUEST['server'],
357
                            'database' => $_REQUEST['database'],
358
                            'schema'   => $_REQUEST['schema'],
359
                            'table'    => $_REQUEST['table'],
360
                        ],
361
                    ],
362
                ],
363
                'content' => $this->lang['straddcolumn'],
364
            ],
365
            'alter'     => [
366
                'attr'    => [
367
                    'href' => [
368
                        'url'     => 'tblproperties',
369
                        'urlvars' => [
370
                            'action'   => 'confirm_alter',
371
                            'server'   => $_REQUEST['server'],
372
                            'database' => $_REQUEST['database'],
373
                            'schema'   => $_REQUEST['schema'],
374
                            'table'    => $_REQUEST['table'],
375
                        ],
376
                    ],
377
                ],
378
                'content' => $this->lang['stralter'],
379
            ],
380
        ];
381
        $this->printNavLinks($navlinks, 'tblproperties-tblproperties', get_defined_vars());
382
    }
383
384
    public function doTree()
385
    {
386
        $misc = $this->misc;
387
        $data = $misc->getDatabaseAccessor();
388
389
        $columns = $data->getTableAttributes($_REQUEST['table']);
390
        $reqvars = $misc->getRequestVars('column');
391
392
        $attrs = [
393
            'text'       => Decorator::field('attname'),
394
            'action'     => Decorator::actionurl(
395
                'colproperties',
396
                $reqvars,
397
                [
398
                    'table'  => $_REQUEST['table'],
399
                    'column' => Decorator::field('attname'),
400
                ]
401
            ),
402
            'icon'       => 'Column',
403
            'iconAction' => Decorator::url(
404
                'display',
405
                $reqvars,
406
                [
407
                    'table'  => $_REQUEST['table'],
408
                    'column' => Decorator::field('attname'),
409
                    'query'  => Decorator::replace(
410
                        'SELECT "%column%", count(*) AS "count" FROM "%table%" GROUP BY "%column%" ORDER BY "%column%"',
411
                        [
412
                            '%column%' => Decorator::field('attname'),
413
                            '%table%'  => $_REQUEST['table'],
414
                        ]
415
                    ),
416
                ]
417
            ),
418
            'toolTip'    => Decorator::field('comment'),
419
        ];
420
421
        return $this->printTree($columns, $attrs, 'tblcolumns');
422
    }
423
424
    public function doSaveAlter()
425
    {
426
        $misc = $this->misc;
427
        $data = $misc->getDatabaseAccessor();
428
429
        // For databases that don't allow owner change
430
        $this->coalesceArr($_POST, 'owner', '');
431
432
        // Default tablespace to null if it isn't set
433
        $this->coalesceArr($_POST, 'tablespace', null);
434
435
        $this->coalesceArr($_POST, 'newschema', null);
436
437
        $status = $data->alterTable($_POST['table'], $_POST['name'], $_POST['owner'], $_POST['newschema'], $_POST['comment'], $_POST['tablespace']);
438
        if (0 == $status) {
439
            // If table has been renamed, need to change to the new name and
440
            // reload the browser frame.
441
            if ($_POST['table'] != $_POST['name']) {
442
                // Jump them to the new table name
443
                $_REQUEST['table'] = $_POST['name'];
444
                // Force a browser reload
445
                $misc->setReloadBrowser(true);
446
            }
447
            // If schema has changed, need to change to the new schema and reload the browser
448
            if (!empty($_POST['newschema']) && ($_POST['newschema'] != $data->_schema)) {
449
                // Jump them to the new sequence schema
450
                $misc->setCurrentSchema($_POST['newschema']);
451
                $misc->setReloadBrowser(true);
452
            }
453
            $this->doDefault($this->lang['strtablealtered']);
454
        } else {
455
            $this->doAlter($this->lang['strtablealteredbad']);
456
        }
457
    }
458
459
    /**
460
     * Function to allow altering of a table.
461
     *
462
     * @param mixed $msg
463
     */
464
    public function doAlter($msg = '')
465
    {
466
        $misc = $this->misc;
467
        $data = $misc->getDatabaseAccessor();
468
469
        $this->printTrail('table');
470
        $this->printTitle($this->lang['stralter'], 'pg.table.alter');
471
        $this->printMsg($msg);
472
473
        // Fetch table info
474
        $table = $data->getTable($_REQUEST['table']);
475
        // Fetch all users
476
        $users       = $data->getUsers();
477
        $tablespaces = null;
478
        // Fetch all tablespaces from the database
479
        if ($data->hasTablespaces()) {
480
            $tablespaces = $data->getTablespaces(true);
481
        }
482
483
        if ($table->recordCount() > 0) {
484
            $this->coalesceArr($_POST, 'name', $table->fields['relname']);
485
486
            $this->coalesceArr($_POST, 'owner', $table->fields['relowner']);
487
488
            $this->coalesceArr($_POST, 'newschema', $table->fields['nspname']);
489
490
            $this->coalesceArr($_POST, 'comment', $table->fields['relcomment']);
491
492
            if ($data->hasTablespaces() && !isset($_POST['tablespace'])) {
493
                $_POST['tablespace'] = $table->fields['tablespace'];
494
            }
495
496
            echo '<form action="'.\SUBFOLDER.'/src/views/tblproperties" method="post">'.PHP_EOL;
497
            echo '<table>'.PHP_EOL;
498
            echo "<tr><th class=\"data left required\">{$this->lang['strname']}</th>".PHP_EOL;
499
            echo '<td class="data1">';
500
            echo "<input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"",
501
            htmlspecialchars($_POST['name'], ENT_QUOTES), '" /></td></tr>'.PHP_EOL;
502
503
            if ($data->isSuperUser()) {
504
                echo "<tr><th class=\"data left required\">{$this->lang['strowner']}</th>".PHP_EOL;
505
                echo '<td class="data1"><select name="owner">';
506
                while (!$users->EOF) {
507
                    $uname = $users->fields['usename'];
508
                    echo '<option value="', htmlspecialchars($uname), '"',
509
                    ($uname == $_POST['owner']) ? ' selected="selected"' : '', '>', htmlspecialchars($uname), '</option>'.PHP_EOL;
510
                    $users->moveNext();
511
                }
512
                echo '</select></td></tr>'.PHP_EOL;
513
            }
514
515
            if ($data->hasAlterTableSchema()) {
516
                $schemas = $data->getSchemas();
517
                echo "<tr><th class=\"data left required\">{$this->lang['strschema']}</th>".PHP_EOL;
518
                echo '<td class="data1"><select name="newschema">';
519
                while (!$schemas->EOF) {
520
                    $schema = $schemas->fields['nspname'];
521
                    echo '<option value="', htmlspecialchars($schema), '"',
522
                    ($schema == $_POST['newschema']) ? ' selected="selected"' : '', '>', htmlspecialchars($schema), '</option>'.PHP_EOL;
523
                    $schemas->moveNext();
524
                }
525
                echo '</select></td></tr>'.PHP_EOL;
526
            }
527
528
            // Tablespace (if there are any)
529
            if ($data->hasTablespaces() && $tablespaces->recordCount() > 0) {
530
                echo "\t<tr>\n\t\t<th class=\"data left\">{$this->lang['strtablespace']}</th>".PHP_EOL;
531
                echo "\t\t<td class=\"data1\">\n\t\t\t<select name=\"tablespace\">".PHP_EOL;
532
                // Always offer the default (empty) option
533
                echo "\t\t\t\t<option value=\"\"",
534
                ('' == $_POST['tablespace']) ? ' selected="selected"' : '', '></option>'.PHP_EOL;
535
                // Display all other tablespaces
536
                while (!$tablespaces->EOF) {
537
                    $spcname = htmlspecialchars($tablespaces->fields['spcname']);
538
                    echo "\t\t\t\t<option value=\"{$spcname}\"",
539
                    ($spcname == $_POST['tablespace']) ? ' selected="selected"' : '', ">{$spcname}</option>".PHP_EOL;
540
                    $tablespaces->moveNext();
541
                }
542
                echo "\t\t\t</select>\n\t\t</td>\n\t</tr>".PHP_EOL;
543
            }
544
545
            echo "<tr><th class=\"data left\">{$this->lang['strcomment']}</th>".PHP_EOL;
546
            echo '<td class="data1">';
547
            echo '<textarea rows="3" cols="32" name="comment">',
548
            htmlspecialchars($_POST['comment']), '</textarea></td></tr>'.PHP_EOL;
549
            echo '</table>'.PHP_EOL;
550
            echo '<p><input type="hidden" name="action" value="alter" />'.PHP_EOL;
551
            echo '<input type="hidden" name="table" value="', htmlspecialchars($_REQUEST['table']), '" />'.PHP_EOL;
552
            echo $misc->form;
553
            echo "<input type=\"submit\" name=\"alter\" value=\"{$this->lang['stralter']}\" />".PHP_EOL;
554
            echo "<input type=\"submit\" name=\"cancel\" value=\"{$this->lang['strcancel']}\" /></p>".PHP_EOL;
555
            echo '</form>'.PHP_EOL;
556
        } else {
557
            echo "<p>{$this->lang['strnodata']}</p>".PHP_EOL;
558
        }
559
    }
560
561
    public function doExport($msg = '')
562
    {
563
        $data    = $this->misc->getDatabaseAccessor();
564
        $subject = 'table';
565
        $object  = $_REQUEST['table'];
566
        // Determine whether or not the table has an object ID
567
        $hasID = $data->hasObjectID($object);
568
        $this->prtrace('$hasID', $hasID);
569
        $this->printTrail('table');
570
        $this->printTabs('table', 'export');
571
        $this->printMsg($msg);
572
573
        echo $this->formHeader();
574
575
        // Data only
576
        echo $this->dataOnly($hasID);
577
578
        // Structure only
579
        echo $this->structureOnly();
580
        // Structure and data
581
        echo $this->structureAndData($hasID);
582
583
        echo $this->displayOrDownload();
584
585
        echo $this->formFooter($subject, $object);
586
    }
587
588
    public function doImport($msg = '')
589
    {
590
        $misc = $this->misc;
591
592
        $this->printTrail('table');
593
        $this->printTabs('table', 'import');
594
        $this->printMsg($msg);
595
596
        // Check that file uploads are enabled
597
        if (ini_get('file_uploads')) {
598
            // Don't show upload option if max size of uploads is zero
599
            $max_size = $misc->inisizeToBytes(ini_get('upload_max_filesize'));
600
            if (is_double($max_size) && $max_size > 0) {
601
                echo '<form action="'.\SUBFOLDER.'/src/views/dataimport" method="post" enctype="multipart/form-data">'.PHP_EOL;
602
                echo '<table>'.PHP_EOL;
603
                echo "\t<tr>\n\t\t<th class=\"data left required\">{$this->lang['strformat']}</th>".PHP_EOL;
604
                echo "\t\t<td><select name=\"format\">".PHP_EOL;
605
                echo "\t\t\t<option value=\"auto\">{$this->lang['strauto']}</option>".PHP_EOL;
606
                echo "\t\t\t<option value=\"csv\">CSV</option>".PHP_EOL;
607
                echo "\t\t\t<option value=\"tab\">{$this->lang['strtabbed']}</option>".PHP_EOL;
608
                if (function_exists('xml_parser_create')) {
609
                    echo "\t\t\t<option value=\"xml\">XML</option>".PHP_EOL;
610
                }
611
                echo "\t\t</select></td>\n\t</tr>".PHP_EOL;
612
                echo "\t<tr>\n\t\t<th class=\"data left required\">{$this->lang['strallowednulls']}</th>".PHP_EOL;
613
                echo "\t\t<td><label><input type=\"checkbox\" name=\"allowednulls[0]\" value=\"\\N\" checked=\"checked\" />{$this->lang['strbackslashn']}</label><br />".PHP_EOL;
614
                echo "\t\t<label><input type=\"checkbox\" name=\"allowednulls[1]\" value=\"NULL\" />NULL</label><br />".PHP_EOL;
615
                echo "\t\t<label><input type=\"checkbox\" name=\"allowednulls[2]\" value=\"\" />{$this->lang['stremptystring']}</label></td>\n\t</tr>".PHP_EOL;
616
                echo "\t<tr>\n\t\t<th class=\"data left required\">{$this->lang['strfile']}</th>".PHP_EOL;
617
                echo "\t\t<td><input type=\"hidden\" name=\"MAX_FILE_SIZE\" value=\"{$max_size}\" />";
618
                echo "<input type=\"file\" name=\"source\" /></td>\n\t</tr>".PHP_EOL;
619
                echo '</table>'.PHP_EOL;
620
                echo '<p><input type="hidden" name="action" value="import" />'.PHP_EOL;
621
                echo $misc->form;
622
                echo '<input type="hidden" name="table" value="', htmlspecialchars($_REQUEST['table']), '" />'.PHP_EOL;
623
                echo "<input type=\"submit\" value=\"{$this->lang['strimport']}\" /></p>".PHP_EOL;
624
                echo '</form>'.PHP_EOL;
625
            }
626
        } else {
627
            echo "<p>{$this->lang['strnouploads']}</p>".PHP_EOL;
628
        }
629
    }
630
631
    /**
632
     * Displays a screen where they can add a column.
633
     *
634
     * @param mixed $msg
635
     */
636
    public function doAddColumn($msg = '')
637
    {
638
        $misc = $this->misc;
639
        $data = $misc->getDatabaseAccessor();
640
641
        $this->coalesceArr($_REQUEST, 'stage', 1);
642
643
        switch ($_REQUEST['stage']) {
644
            case 1:
645
                // Set variable defaults
646
                $this->coalesceArr($_POST, 'field', '');
647
648
                $this->coalesceArr($_POST, 'type', '');
649
650
                $this->coalesceArr($_POST, 'array', '');
651
652
                $this->coalesceArr($_POST, 'length', '');
653
654
                $this->coalesceArr($_POST, 'default', '');
655
656
                $this->coalesceArr($_POST, 'comment', '');
657
658
                // Fetch all available types
659
                $types        = $data->getTypes(true, false, true);
660
                $types_for_js = [];
661
662
                $this->printTrail('table');
663
                $this->printTitle($this->lang['straddcolumn'], 'pg.column.add');
664
                $this->printMsg($msg);
665
666
                echo '<script src="'.\SUBFOLDER.'/assets/js/tables.js" type="text/javascript"></script>';
667
                echo '<form action="'.\SUBFOLDER.'/src/views/tblproperties" method="post">'.PHP_EOL;
668
669
                // Output table header
670
                echo '<table>'.PHP_EOL;
671
                echo "<tr><th class=\"data required\">{$this->lang['strname']}</th>\n<th colspan=\"2\" class=\"data required\">{$this->lang['strtype']}</th>".PHP_EOL;
672
                echo "<th class=\"data\">{$this->lang['strlength']}</th>".PHP_EOL;
673
                if ($data->hasCreateFieldWithConstraints()) {
674
                    echo "<th class=\"data\">{$this->lang['strnotnull']}</th>\n<th class=\"data\">{$this->lang['strdefault']}</th>".PHP_EOL;
675
                }
676
677
                echo "<th class=\"data\">{$this->lang['strcomment']}</th></tr>".PHP_EOL;
678
679
                echo "<tr><td><input name=\"field\" size=\"16\" maxlength=\"{$data->_maxNameLen}\" value=\"",
680
                htmlspecialchars($_POST['field']), '" /></td>'.PHP_EOL;
681
                echo "<td><select  class=\"select2\" name=\"type\" id=\"type\" onchange=\"checkLengths(document.getElementById('type').value,'');\">".PHP_EOL;
682
                // Output any "magic" types.  This came in with the alter column type so we'll check that
683
                if ($data->hasMagicTypes()) {
684
                    foreach ($data->extraTypes as $v) {
685
                        $types_for_js[] = strtolower($v);
686
                        echo "\t<option value=\"", htmlspecialchars($v), '"',
687
                        ($v == $_POST['type']) ? ' selected="selected"' : '', '>',
688
                        $misc->printVal($v), '</option>'.PHP_EOL;
689
                    }
690
                }
691
                while (!$types->EOF) {
692
                    $typname        = $types->fields['typname'];
693
                    $types_for_js[] = $typname;
694
                    echo "\t<option value=\"", htmlspecialchars($typname), '"', ($typname == $_POST['type']) ? ' selected="selected"' : '', '>',
695
                    $misc->printVal($typname), '</option>'.PHP_EOL;
696
                    $types->moveNext();
697
                }
698
                echo '</select></td>'.PHP_EOL;
699
700
                // Output array type selector
701
                echo '<td><select name="array">'.PHP_EOL;
702
                echo "\t<option value=\"\"", ('' == $_POST['array']) ? ' selected="selected"' : '', '></option>'.PHP_EOL;
703
                echo "\t<option value=\"[]\"", ('[]' == $_POST['array']) ? ' selected="selected"' : '', '>[ ]</option>'.PHP_EOL;
704
                echo '</select></td>'.PHP_EOL;
705
                $predefined_size_types = array_intersect($data->predefined_size_types, $types_for_js);
706
                $escaped_predef_types  = []; // the JS escaped array elements
707
                foreach ($predefined_size_types as $value) {
708
                    $escaped_predef_types[] = "'{$value}'";
709
                }
710
711
                echo '<td><input name="length" id="lengths" size="8" value="',
712
                htmlspecialchars($_POST['length']), '" /></td>'.PHP_EOL;
713
                // Support for adding column with not null and default
714
                if ($data->hasCreateFieldWithConstraints()) {
715
                    echo '<td><input type="checkbox" name="notnull"',
716
                    (isset($_REQUEST['notnull'])) ? ' checked="checked"' : '', ' /></td>'.PHP_EOL;
717
                    echo '<td><input name="default" size="20" value="',
718
                    htmlspecialchars($_POST['default']), '" /></td>'.PHP_EOL;
719
                }
720
                echo '<td><input name="comment" size="40" value="',
721
                htmlspecialchars($_POST['comment']), '" /></td></tr>'.PHP_EOL;
722
                echo '</table>'.PHP_EOL;
723
                echo '<p><input type="hidden" name="action" value="add_column" />'.PHP_EOL;
724
                echo '<input type="hidden" name="stage" value="2" />'.PHP_EOL;
725
                echo $misc->form;
726
                echo '<input type="hidden" name="table" value="', htmlspecialchars($_REQUEST['table']), '" />'.PHP_EOL;
727
                if (!$data->hasCreateFieldWithConstraints()) {
728
                    echo '<input type="hidden" name="default" value="" />'.PHP_EOL;
729
                }
730
                echo "<input type=\"submit\" value=\"{$this->lang['stradd']}\" />".PHP_EOL;
731
                echo "<input type=\"submit\" name=\"cancel\" value=\"{$this->lang['strcancel']}\" /></p>".PHP_EOL;
732
                echo '</form>'.PHP_EOL;
733
                echo '<script type="text/javascript">predefined_lengths = new Array('.implode(',', $escaped_predef_types).");checkLengths(document.getElementById('type').value,'');</script>".PHP_EOL;
734
735
                break;
736
            case 2:
737
                // Check inputs
738
                if ('' == trim($_POST['field'])) {
739
                    $_REQUEST['stage'] = 1;
740
                    $this->doAddColumn($this->lang['strcolneedsname']);
741
742
                    return;
743
                }
744
                $this->coalesceArr($_POST, 'length', '');
745
746
                $status = $data->addColumn(
747
                    $_POST['table'],
748
                    $_POST['field'],
749
                    $_POST['type'],
750
                    '' != $_POST['array'],
751
                    $_POST['length'],
752
                    isset($_POST['notnull']),
753
                    $_POST['default'],
754
                    $_POST['comment']
755
                );
756
                if (0 == $status) {
757
                    $misc->setReloadBrowser(true);
758
                    $this->doDefault($this->lang['strcolumnadded']);
759
                } else {
760
                    $_REQUEST['stage'] = 1;
761
                    $this->doAddColumn($this->lang['strcolumnaddedbad']);
762
763
                    return;
764
                }
765
766
                break;
767
            default:
768
                echo "<p>{$this->lang['strinvalidparam']}</p>".PHP_EOL;
769
        }
770
    }
771
772
    /**
773
     * Show confirmation of drop column and perform actual drop.
774
     *
775
     * @param bool $confirm true to ask for confirmation, false to actually drop
776
     */
777
    public function doDrop($confirm = true)
778
    {
779
        $misc = $this->misc;
780
        $data = $misc->getDatabaseAccessor();
781
782
        if ($confirm) {
783
            $this->printTrail('column');
784
            $this->printTitle($this->lang['strdrop'], 'pg.column.drop');
785
786
            echo '<p>'.sprintf($this->lang['strconfdropcolumn'], $misc->printVal($_REQUEST['column']), $misc->printVal($_REQUEST['table'])).'</p>'.PHP_EOL;
787
788
            echo '<form action="'.\SUBFOLDER.'/src/views/tblproperties" method="post">'.PHP_EOL;
789
            echo '<input type="hidden" name="action" value="drop" />'.PHP_EOL;
790
            echo '<input type="hidden" name="table" value="', htmlspecialchars($_REQUEST['table']), '" />'.PHP_EOL;
791
            echo '<input type="hidden" name="column" value="', htmlspecialchars($_REQUEST['column']), '" />'.PHP_EOL;
792
            echo $misc->form;
793
            echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\"> <label for=\"cascade\">{$this->lang['strcascade']}</label></p>".PHP_EOL;
794
            echo "<input type=\"submit\" name=\"drop\" value=\"{$this->lang['strdrop']}\" />".PHP_EOL;
795
            echo "<input type=\"submit\" name=\"cancel\" value=\"{$this->lang['strcancel']}\" />".PHP_EOL;
796
            echo '</form>'.PHP_EOL;
797
        } else {
798
            $status = $data->dropColumn($_POST['table'], $_POST['column'], isset($_POST['cascade']));
799
            if (0 == $status) {
800
                $misc->setReloadBrowser(true);
801
                $this->doDefault($this->lang['strcolumndropped']);
802
            } else {
803
                $this->doDefault($this->lang['strcolumndroppedbad']);
804
            }
805
        }
806
    }
807
}
808