Passed
Pull Request — develop (#92)
by Felipe
04:25
created

src/controllers/ColpropertiesController.php (4 issues)

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