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