Passed
Push — develop ( e54c4a...a6767a )
by Felipe
11:32 queued 05:47
created

ColpropertiesController::render()   C

Complexity

Conditions 8
Paths 16

Size

Total Lines 35
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Importance

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