Passed
Push — develop ( c6c0b1...90e9a5 )
by Felipe
10:30 queued 02:43
created

ColpropertiesController   B

Complexity

Total Complexity 38

Size/Duplication

Total Lines 384
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 38
dl 0
loc 384
rs 8.3999
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
C doDefault() 0 153 8
D render() 0 35 9
D doAlter() 0 171 21
1
<?php
2
3
/**
4
 * PHPPgAdmin v6.0.0-beta.45
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 ColpropertiesController extends BaseController
17
{
18
    public $tableName        = '';
19
    public $table_place      = 'colproperties-colproperties';
20
    public $controller_title = 'strtables';
21
22
    /**
23
     * Default method to render the controller according to the action parameter.
24
     */
25
    public function render()
26
    {
27
        if (isset($_REQUEST['table']) && !empty($_REQUEST['table'])) {
28
            $this->tableName = &$_REQUEST['table'];
29
        } elseif (isset($_REQUEST['view'])) {
30
            $this->tableName = &$_REQUEST['view'];
31
        } elseif (isset($_REQUEST['matview'])) {
32
            $this->tableName = &$_REQUEST['matview'];
33
        } else {
34
            $this->halt($this->lang['strnotableprovided']);
35
        }
36
37
        $this->printHeader($this->headerTitle('', '', $this->tableName), null, true, 'header_select2.twig');
38
        $this->printBody();
39
40
        if (isset($_REQUEST['view']) || isset($_REQUEST['matview'])) {
41
            $this->doDefault(null, false);
42
        } else {
43
            switch ($this->action) {
44
                case 'properties':
45
                    if (isset($_POST['cancel'])) {
46
                        $this->doDefault();
47
                    } else {
48
                        $this->doAlter();
49
                    }
50
51
                    break;
52
                default:
53
                    $this->doDefault();
54
55
                    break;
56
            }
57
        }
58
59
        $this->printFooter();
60
    }
61
62
    /**
63
     * Show default list of columns in the table.
64
     *
65
     * @param string $msg     message to display
66
     * @param bool   $isTable tells if we're showing table properties
67
     */
68
    public function doDefault($msg = '', $isTable = true)
69
    {
70
        if (!isset($_REQUEST['table']) || empty($_REQUEST['table'])) {
71
            $isTable = false;
72
        }
73
        $data = $this->misc->getDatabaseAccessor();
74
75
        $attPre = function (&$rowdata) use ($data) {
76
            $rowdata->fields['+type'] = $data->formatType($rowdata->fields['type'], $rowdata->fields['atttypmod']);
77
        };
78
79
        if (empty($_REQUEST['column'])) {
80
            $msg .= "<br/>{$this->lang['strnoobjects']}";
81
        }
82
83
        $this->printTrail('column');
84
        //$this->printTitle($this->lang['strcolprop']);
85
        $this->printTabs('column', 'properties');
86
        $this->printMsg($msg);
87
88
        if (!empty($_REQUEST['column'])) {
89
            // Get table
90
            $tdata = $data->getTable($this->tableName);
91
            //\Kint::dump($tdata);
92
            // Get columns
93
            $attrs = $data->getTableAttributes($this->tableName, $_REQUEST['column']);
94
95
            // Show comment if any
96
            if (null !== $attrs->fields['comment']) {
97
                echo '<p class="comment">', $this->misc->printVal($attrs->fields['comment']), "</p>\n";
98
            }
99
            $this->prtrace('$isTable', $isTable);
100
101
            $column = [
102
                'column' => [
103
                    'title' => $this->lang['strcolumn'],
104
                    'field' => Decorator::field('attname'),
105
                ],
106
                'type'   => [
107
                    'title' => $this->lang['strtype'],
108
                    'field' => Decorator::field('+type'),
109
                ],
110
            ];
111
112
            if ($isTable) {
113
                $column['notnull'] = [
114
                    'title'  => $this->lang['strnotnull'],
115
                    'field'  => Decorator::field('attnotnull'),
116
                    'type'   => 'bool',
117
                    'params' => ['true' => 'NOT NULL', 'false' => ''],
118
                ];
119
                $column['default'] = [
120
                    'title' => $this->lang['strdefault'],
121
                    'field' => Decorator::field('adsrc'),
122
                ];
123
            }
124
125
            $actions = [];
126
            echo $this->printTable($attrs, $column, $actions, $this->table_place, null, $attPre);
127
128
            echo "<br />\n";
129
130
            $f_attname = $_REQUEST['column'];
131
            $f_table   = $this->tableName;
132
            $f_schema  = $data->_schema;
133
            $data->fieldClean($f_attname);
134
            $data->fieldClean($f_table);
135
            $data->fieldClean($f_schema);
136
137
            if ($isTable) {
138
                $navlinks = [
139
                    'browse' => [
140
                        'attr'    => [
141
                            'href' => [
142
                                'url'     => 'display',
143
                                'method'  => 'post',
144
                                'urlvars' => [
145
                                    'subject'   => 'column',
146
                                    'server'    => $_REQUEST['server'],
147
                                    'database'  => $_REQUEST['database'],
148
                                    'schema'    => $_REQUEST['schema'],
149
                                    'table'     => $this->tableName,
150
                                    'column'    => $_REQUEST['column'],
151
                                    'return'    => 'column',
152
                                    'f_attname' => $f_attname,
153
                                    'f_table'   => $f_table,
154
                                    'f_schema'  => $f_schema,
155
                                ],
156
                            ],
157
                        ],
158
                        'content' => $this->lang['strbrowse'],
159
                    ],
160
                    'alter'  => [
161
                        'attr'    => [
162
                            'href' => [
163
                                'url'     => 'colproperties',
164
                                'urlvars' => [
165
                                    'action'   => 'properties',
166
                                    'server'   => $_REQUEST['server'],
167
                                    'database' => $_REQUEST['database'],
168
                                    'schema'   => $_REQUEST['schema'],
169
                                    'table'    => $this->tableName,
170
                                    'column'   => $_REQUEST['column'],
171
                                ],
172
                            ],
173
                        ],
174
                        'content' => $this->lang['stralter'],
175
                    ],
176
                    'drop'   => [
177
                        'attr'    => [
178
                            'href' => [
179
                                'url'     => 'tblproperties',
180
                                'urlvars' => [
181
                                    'action'   => 'confirm_drop',
182
                                    'server'   => $_REQUEST['server'],
183
                                    'database' => $_REQUEST['database'],
184
                                    'schema'   => $_REQUEST['schema'],
185
                                    'table'    => $this->tableName,
186
                                    'column'   => $_REQUEST['column'],
187
                                ],
188
                            ],
189
                        ],
190
                        'content' => $this->lang['strdrop'],
191
                    ],
192
                ];
193
            } else {
194
                // Browse link
195
                $navlinks = [
196
                    'browse' => [
197
                        'attr'    => [
198
                            'href' => [
199
                                'url'     => 'display',
200
                                'method'  => 'post',
201
                                'urlvars' => [
202
                                    'subject'   => 'column',
203
                                    'server'    => $_REQUEST['server'],
204
                                    'database'  => $_REQUEST['database'],
205
                                    'schema'    => $_REQUEST['schema'],
206
                                    'view'      => $this->tableName,
207
                                    'column'    => $_REQUEST['column'],
208
                                    'return'    => 'column',
209
                                    'f_attname' => $f_attname,
210
                                    'f_table'   => $f_table,
211
                                    'f_schema'  => $f_schema,
212
                                ],
213
                            ],
214
                        ],
215
                        'content' => $this->lang['strbrowse'],
216
                    ],
217
                ];
218
            }
219
220
            $this->printNavLinks($navlinks, $this->table_place, get_defined_vars());
221
        }
222
    }
223
224
    /**
225
     * Displays a screen where they can alter a column.
226
     *
227
     * @param mixed $msg
228
     */
229
    public function doAlter($msg = '')
230
    {
231
        $data = $this->misc->getDatabaseAccessor();
232
233
        $this->coalesceArr($_REQUEST, 'stage', 1);
234
235
        $this->prtrace('$_REQUEST', $_REQUEST, 'msg', $msg);
236
237
        switch ($_REQUEST['stage']) {
238
            case 1:
239
                $this->printTrail('column');
240
                $this->printTitle($this->lang['stralter'], 'pg.column.alter');
241
                $this->printMsg($msg);
242
243
                echo '<script src="' . \SUBFOLDER . '/assets/js/tables.js" type="text/javascript"></script>';
244
                echo '<form action="' . \SUBFOLDER . "/src/views/colproperties\" method=\"post\">\n";
245
246
                // Output table header
247
                echo "<table>\n";
248
                echo "<tr><th class=\"data required\">{$this->lang['strname']}</th>\n";
249
                if ($data->hasAlterColumnType()) {
250
                    echo "<th class=\"data required\" colspan=\"2\">{$this->lang['strtype']}</th>\n";
251
                    echo "<th class=\"data\">{$this->lang['strlength']}</th>\n";
252
                } else {
253
                    echo "<th class=\"data required\">{$this->lang['strtype']}</th>\n";
254
                }
255
                echo "<th class=\"data\">{$this->lang['strnotnull']}</th>\n<th class=\"data\">{$this->lang['strdefault']}</th>\n<th class=\"data\">{$this->lang['strcomment']}</th></tr>\n";
256
257
                $column                       = $data->getTableAttributes($_REQUEST['table'], $_REQUEST['column']);
258
                $column->fields['attnotnull'] = $data->phpBool($column->fields['attnotnull']);
259
260
                // Upon first drawing the screen, load the existing column information
261
                // from the database.
262
                if (!isset($_REQUEST['default'])) {
263
                    $_REQUEST['field'] = $column->fields['attname'];
264
                    $_REQUEST['type']  = $column->fields['base_type'];
265
                    // Check to see if its' an array type...
266
                    // XXX: HACKY
267
                    if ('[]' == substr($column->fields['base_type'], strlen($column->fields['base_type']) - 2)) {
268
                        $_REQUEST['type']  = substr($column->fields['base_type'], 0, strlen($column->fields['base_type']) - 2);
269
                        $_REQUEST['array'] = '[]';
270
                    } else {
271
                        $_REQUEST['type']  = $column->fields['base_type'];
272
                        $_REQUEST['array'] = '';
273
                    }
274
                    // To figure out the length, look in the brackets :(
275
                    // XXX: HACKY
276
                    if ($column->fields['type'] != $column->fields['base_type'] && preg_match('/\\(([0-9, ]*)\\)/', $column->fields['type'], $bits)) {
277
                        $_REQUEST['length'] = $bits[1];
278
                    } else {
279
                        $_REQUEST['length'] = '';
280
                    }
281
282
                    $_REQUEST['default'] = $_REQUEST['olddefault'] = $column->fields['adsrc'];
283
                    if ($column->fields['attnotnull']) {
284
                        $_REQUEST['notnull'] = 'YES';
285
                    }
286
287
                    $_REQUEST['comment'] = $column->fields['comment'];
288
                }
289
290
                // Column name
291
                echo "<tr><td><input name=\"field\" size=\"16\" maxlength=\"{$data->_maxNameLen}\" value=\"",
292
                htmlspecialchars($_REQUEST['field']), "\" /></td>\n";
293
294
                // Column type
295
                $escaped_predef_types = []; // the JS escaped array elements
296
                if ($data->hasAlterColumnType()) {
297
                    // Fetch all available types
298
                    $types        = $data->getTypes(true, false, true);
299
                    $types_for_js = [];
300
301
                    echo "<td><select name=\"type\" id=\"type\" class=\"select2\" onchange=\"checkLengths(document.getElementById('type').value,'');\">" . "\n";
302
                    while (!$types->EOF) {
303
                        $typname        = $types->fields['typname'];
304
                        $types_for_js[] = $typname;
305
                        echo "\t<option value=\"", htmlspecialchars($typname), '"', ($typname == $_REQUEST['type']) ? ' selected="selected"' : '', '>',
306
                        $this->misc->printVal($typname), "</option>\n";
307
                        $types->moveNext();
308
                    }
309
                    echo "</select>\n";
310
                    echo "</td>\n";
311
312
                    // Output array type selector
313
                    echo "<td><select name=\"array\">\n";
314
                    echo "\t<option value=\"\"", ('' == $_REQUEST['array']) ? ' selected="selected"' : '', "></option>\n";
315
                    echo "\t<option value=\"[]\"", ('[]' == $_REQUEST['array']) ? ' selected="selected"' : '', ">[ ]</option>\n";
316
                    echo "</select></td>\n";
317
                    $predefined_size_types = array_intersect($data->predefined_size_types, $types_for_js);
318
                    foreach ($predefined_size_types as $value) {
319
                        $escaped_predef_types[] = "'{$value}'";
320
                    }
321
322
                    echo '<td><input name="length" id="lengths" size="8" value="',
323
                    htmlspecialchars($_REQUEST['length']), "\" /></td>\n";
324
                } else {
325
                    // Otherwise draw the read-only type name
326
                    echo '<td>', $this->misc->printVal($data->formatType($column->fields['type'], $column->fields['atttypmod'])), "</td>\n";
327
                }
328
329
                echo '<td><input type="checkbox" name="notnull"', (isset($_REQUEST['notnull'])) ? ' checked="checked"' : '', " /></td>\n";
330
                echo '<td><input name="default" size="20" value="',
331
                htmlspecialchars($_REQUEST['default']), "\" /></td>\n";
332
                echo '<td><input name="comment" size="40" value="',
333
                htmlspecialchars($_REQUEST['comment']), "\" /></td></tr>\n";
334
                echo "</table>\n";
335
                echo "<p><input type=\"hidden\" name=\"action\" value=\"properties\" />\n";
336
                echo "<input type=\"hidden\" name=\"stage\" value=\"2\" />\n";
337
                echo $this->misc->form;
338
                echo '<input type="hidden" name="table" value="', htmlspecialchars($_REQUEST['table']), "\" />\n";
339
                echo '<input type="hidden" name="column" value="', htmlspecialchars($_REQUEST['column']), "\" />\n";
340
                echo '<input type="hidden" name="olddefault" value="', htmlspecialchars($_REQUEST['olddefault']), "\" />\n";
341
                if ($column->fields['attnotnull']) {
342
                    echo "<input type=\"hidden\" name=\"oldnotnull\" value=\"on\" />\n";
343
                }
344
345
                echo '<input type="hidden" name="oldtype" value="', htmlspecialchars($data->formatType($column->fields['type'], $column->fields['atttypmod'])), "\" />\n";
346
                // Add hidden variables to suppress error notices if we don't support altering column type
347
                if (!$data->hasAlterColumnType()) {
348
                    echo '<input type="hidden" name="type" value="', htmlspecialchars($_REQUEST['type']), "\" />\n";
349
                    echo '<input type="hidden" name="length" value="', htmlspecialchars($_REQUEST['length']), "\" />\n";
350
                    echo '<input type="hidden" name="array" value="', htmlspecialchars($_REQUEST['array']), "\" />\n";
351
                }
352
                echo "<input type=\"submit\" value=\"{$this->lang['stralter']}\" />\n";
353
                echo "<input type=\"submit\" name=\"cancel\" value=\"{$this->lang['strcancel']}\" /></p>\n";
354
                echo "</form>\n";
355
                echo '<script type="text/javascript">predefined_lengths = new Array(' . implode(',', $escaped_predef_types) . ");checkLengths(document.getElementById('type').value,'');</script>\n";
356
357
                break;
358
            case 2:
359
                // Check inputs
360
                if ('' == trim($_REQUEST['field'])) {
361
                    $_REQUEST['stage'] = 1;
362
                    $this->doAlter($this->lang['strcolneedsname']);
363
364
                    return;
365
                }
366
                $this->coalesceArr($_REQUEST, 'length', '');
367
368
                list($status, $sql) = $data->alterColumn(
369
                    $_REQUEST['table'],
370
                    $_REQUEST['column'],
371
                    $_REQUEST['field'],
372
                    isset($_REQUEST['notnull']),
373
                    isset($_REQUEST['oldnotnull']),
374
                    $_REQUEST['default'],
375
                    $_REQUEST['olddefault'],
376
                    $_REQUEST['type'],
377
                    $_REQUEST['length'],
378
                    $_REQUEST['array'],
379
                    $_REQUEST['oldtype'],
380
                    $_REQUEST['comment']
381
                );
382
383
                $this->prtrace('status', $status, 'sql', $sql);
384
                if (0 == $status) {
385
                    if ($_REQUEST['column'] != $_REQUEST['field']) {
386
                        $_REQUEST['column'] = $_REQUEST['field'];
387
                        $this->misc->setReloadBrowser(true);
388
                    }
389
                    $this->doDefault($sql . "<br/>{$this->lang['strcolumnaltered']}");
390
                } else {
391
                    $_REQUEST['stage'] = 1;
392
                    $this->doAlter($sql . "<br/>{$this->lang['strcolumnalteredbad']}");
393
394
                    return;
395
                }
396
397
                break;
398
            default:
399
                echo "<p>{$this->lang['strinvalidparam']}</p>\n";
400
        }
401
    }
402
}
403