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

src/controllers/SchemasController.php (9 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 SchemasController extends BaseController
15
{
16
    public $controller_name = 'SchemasController';
17
18
    /**
19
     * Default method to render the controller according to the action parameter.
20
     */
21
    public function render()
22
    {
23
        $conf = $this->conf;
24
25
        $lang   = $this->lang;
26
        $action = $this->action;
27
28
        if ('tree' == $action) {
29
            return $this->doTree();
30
        }
31
        if ('subtree' == $action) {
32
            return $this->doSubTree();
33
        }
34
35
        if (isset($_POST['cancel'])) {
36
            $action = '';
37
        }
38
39
        $header_template = 'header.twig';
40
        $footer_template = 'footer.twig';
41
42
        ob_start();
43
        switch ($action) {
44
            case 'create':
45
                if (isset($_POST['create'])) {
46
                    $this->doSaveCreate();
47
                } else {
48
                    $this->doCreate();
49
                }
50
51
                break;
52
            case 'alter':
53
                if (isset($_POST['alter'])) {
54
                    $this->doSaveAlter();
55
                } else {
56
                    $this->doAlter();
57
                }
58
59
                break;
60
            case 'drop':
61
                if (isset($_POST['drop'])) {
62
                    $this->doDrop(false);
63
                } else {
64
                    $this->doDrop(true);
65
                }
66
67
                break;
68
            case 'export':
69
                $this->doExport();
70
71
                break;
72
            default:
73
                $header_template = 'header_datatables.twig';
74
                $this->doDefault();
75
76
                break;
77
        }
78
79
        $output = ob_get_clean();
80
81
        $this->printHeader($lang['strschemas'], null, true, $header_template);
82
        $this->printBody();
83
84
        echo $output;
85
86
        return $this->printFooter();
87
    }
88
89
    /**
90
     * Show default list of schemas in the database.
91
     *
92
     * @param mixed $msg
1 ignored issue
show
Missing parameter comment
Loading history...
93
     */
94
    public function doDefault($msg = '')
95
    {
96
        $conf = $this->conf;
97
98
        $lang = $this->lang;
99
        $data = $this->misc->getDatabaseAccessor();
100
101
        $this->printTrail('database');
102
        $this->printTabs('database', 'schemas');
103
        $this->printMsg($msg);
104
105
        // Check that the DB actually supports schemas
106
        $schemas = $data->getSchemas();
107
108
        $columns = [
109
            'schema' => [
110
                'title' => $lang['strschema'],
111
                'field' => Decorator::field('nspname'),
112
                'url'   => \SUBFOLDER."/redirect/schema?{$this->misc->href}&amp;",
113
                'vars'  => ['schema' => 'nspname'],
114
            ],
115
            'owner' => [
116
                'title' => $lang['strowner'],
117
                'field' => Decorator::field('nspowner'),
118
            ],
119
            'actions' => [
120
                'title' => $lang['stractions'],
121
            ],
122
            'comment' => [
123
                'title' => $lang['strcomment'],
124
                'field' => Decorator::field('nspcomment'),
125
            ],
126
        ];
127
128
        $actions = [
129
            'multiactions' => [
130
                'keycols' => ['nsp' => 'nspname'],
131
                'url'     => 'schemas.php',
132
            ],
133
            'drop' => [
134
                'content' => $lang['strdrop'],
135
                'attr'    => [
136
                    'href' => [
137
                        'url'     => 'schemas.php',
138
                        'urlvars' => [
139
                            'action' => 'drop',
140
                            'nsp'    => Decorator::field('nspname'),
141
                        ],
142
                    ],
143
                ],
144
                'multiaction' => 'drop',
145
            ],
146
            'privileges' => [
147
                'content' => $lang['strprivileges'],
148
                'attr'    => [
149
                    'href' => [
150
                        'url'     => 'privileges.php',
151
                        'urlvars' => [
152
                            'subject' => 'schema',
153
                            'schema'  => Decorator::field('nspname'),
154
                        ],
155
                    ],
156
                ],
157
            ],
158
            'alter' => [
159
                'content' => $lang['stralter'],
160
                'attr'    => [
161
                    'href' => [
162
                        'url'     => 'schemas.php',
163
                        'urlvars' => [
164
                            'action' => 'alter',
165
                            'schema' => Decorator::field('nspname'),
166
                        ],
167
                    ],
168
                ],
169
            ],
170
        ];
171
172
        if (!$data->hasAlterSchema()) {
173
            unset($actions['alter']);
174
        }
175
176
        echo $this->printTable($schemas, $columns, $actions, 'schemas-schemas', $lang['strnoschemas']);
177
178
        $this->printNavLinks(['create' => [
179
            'attr' => [
180
                'href' => [
181
                    'url'     => 'schemas.php',
182
                    'urlvars' => [
183
                        'action'   => 'create',
184
                        'server'   => $_REQUEST['server'],
185
                        'database' => $_REQUEST['database'],
186
                    ],
187
                ],
188
            ],
189
            'content' => $lang['strcreateschema'],
190
        ]], 'schemas-schemas', get_defined_vars());
191
    }
192
193
    /**
194
     * Generate XML for the browser tree.
195
     */
196
    public function doTree()
197
    {
198
        $conf = $this->conf;
199
200
        $lang = $this->lang;
0 ignored issues
show
The assignment to $lang is dead and can be removed.
Loading history...
201
        $data = $this->misc->getDatabaseAccessor();
202
203
        $schemas = $data->getSchemas();
204
205
        $reqvars = $this->misc->getRequestVars('schema');
206
207
        //$this->prtrace($reqvars);
208
209
        $attrs = [
210
            'text'    => Decorator::field('nspname'),
211
            'icon'    => 'Schema',
212
            'toolTip' => Decorator::field('nspcomment'),
213
            'action'  => Decorator::redirecturl(
214
                'redirect.php',
215
                $reqvars,
216
                [
217
                    'subject' => 'schema',
218
                    'schema'  => Decorator::field('nspname'),
219
                ]
220
            ),
221
            'branch' => Decorator::url(
222
                'schemas.php',
223
                $reqvars,
224
                [
225
                    'action' => 'subtree',
226
                    'schema' => Decorator::field('nspname'),
227
                ]
228
            ),
229
        ];
230
231
        $this->printTree($schemas, $attrs, 'schemas');
232
    }
233
234
    public function doSubTree()
235
    {
236
        $conf = $this->conf;
237
238
        $lang = $this->lang;
0 ignored issues
show
The assignment to $lang is dead and can be removed.
Loading history...
239
        $data = $this->misc->getDatabaseAccessor();
240
241
        $tabs = $this->misc->getNavTabs('schema');
242
243
        $items = $this->adjustTabsForTree($tabs);
244
245
        $reqvars = $this->misc->getRequestVars('schema');
246
247
        //$this->prtrace($reqvars);
248
249
        $attrs = [
250
            'text'   => Decorator::field('title'),
251
            'icon'   => Decorator::field('icon'),
252
            'action' => Decorator::actionurl(
253
                Decorator::field('url'),
254
                $reqvars,
255
                Decorator::field('urlvars', [])
256
            ),
257
            'branch' => Decorator::url(
258
                Decorator::field('url'),
259
                $reqvars,
260
                Decorator::field('urlvars'),
261
                ['action' => 'tree']
262
            ),
263
        ];
264
265
        $this->printTree($items, $attrs, 'schema');
266
    }
267
268
    /**
269
     * Displays a screen where they can enter a new schema.
270
     *
271
     * @param mixed $msg
1 ignored issue
show
Missing parameter comment
Loading history...
272
     */
273
    public function doCreate($msg = '')
274
    {
275
        $lang = $this->lang;
276
        $data = $this->misc->getDatabaseAccessor();
277
278
        $server_info = $this->misc->getServerInfo();
279
280
        if (!isset($_POST['formName'])) {
281
            $_POST['formName'] = '';
282
        }
283
284
        if (!isset($_POST['formAuth'])) {
285
            $_POST['formAuth'] = $server_info['username'];
286
        }
287
288
        if (!isset($_POST['formSpc'])) {
289
            $_POST['formSpc'] = '';
290
        }
291
292
        if (!isset($_POST['formComment'])) {
293
            $_POST['formComment'] = '';
294
        }
295
296
        // Fetch all users from the database
297
        $users = $data->getUsers();
298
299
        $this->printTrail('database');
300
        $this->printTitle($lang['strcreateschema'], 'pg.schema.create');
301
        $this->printMsg($msg);
302
303
        echo '<form action="'.\SUBFOLDER.'/src/views/schemas.php" method="post">'."\n";
304
        echo "<table style=\"width: 100%\">\n";
305
        echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n";
306
        echo "\t\t<td class=\"data1\"><input name=\"formName\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"",
307
        htmlspecialchars($_POST['formName']), "\" /></td>\n\t</tr>\n";
308
        // Owner
309
        echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strowner']}</th>\n";
310
        echo "\t\t<td class=\"data1\">\n\t\t\t<select name=\"formAuth\">\n";
311
        while (!$users->EOF) {
312
            $uname = htmlspecialchars($users->fields['usename']);
313
            echo "\t\t\t\t<option value=\"{$uname}\"",
314
            ($uname == $_POST['formAuth']) ? ' selected="selected"' : '', ">{$uname}</option>\n";
315
            $users->moveNext();
316
        }
317
        echo "\t\t\t</select>\n\t\t</td>\n\t</tr>\n";
318
        echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcomment']}</th>\n";
319
        echo "\t\t<td class=\"data1\"><textarea name=\"formComment\" rows=\"3\" cols=\"32\">",
320
        htmlspecialchars($_POST['formComment']), "</textarea></td>\n\t</tr>\n";
321
322
        echo "</table>\n";
323
        echo "<p>\n";
324
        echo "<input type=\"hidden\" name=\"action\" value=\"create\" />\n";
325
        echo '<input type="hidden" name="database" value="', htmlspecialchars($_REQUEST['database']), "\" />\n";
326
        echo $this->misc->form;
327
        echo "<input type=\"submit\" name=\"create\" value=\"{$lang['strcreate']}\" />\n";
328
        echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n";
329
        echo "</p>\n";
330
        echo "</form>\n";
331
    }
332
333
    /**
334
     * Actually creates the new schema in the database.
335
     */
336
    public function doSaveCreate()
337
    {
338
        $lang = $this->lang;
339
        $data = $this->misc->getDatabaseAccessor();
340
341
        // Check that they've given a name
342
        if ('' == $_POST['formName']) {
343
            $this->doCreate($lang['strschemaneedsname']);
344
        } else {
345
            $status = $data->createSchema($_POST['formName'], $_POST['formAuth'], $_POST['formComment']);
346
            if (0 == $status) {
347
                $this->misc->setReloadBrowser(true);
348
                $this->doDefault($lang['strschemacreated']);
349
            } else {
350
                $this->doCreate($lang['strschemacreatedbad']);
351
            }
352
        }
353
    }
354
355
    /**
356
     * Display a form to permit editing schema properies.
357
     * TODO: permit changing owner.
358
     *
359
     * @param mixed $msg
1 ignored issue
show
Missing parameter comment
Loading history...
360
     */
361
    public function doAlter($msg = '')
362
    {
363
        $lang = $this->lang;
364
        $data = $this->misc->getDatabaseAccessor();
365
366
        $this->printTrail('schema');
367
        $this->printTitle($lang['stralter'], 'pg.schema.alter');
368
        $this->printMsg($msg);
369
370
        $schema = $data->getSchemaByName($_REQUEST['schema']);
371
        if ($schema->recordCount() > 0) {
372
            if (!isset($_POST['comment'])) {
373
                $_POST['comment'] = $schema->fields['nspcomment'];
374
            }
375
376
            if (!isset($_POST['schema'])) {
377
                $_POST['schema'] = $_REQUEST['schema'];
378
            }
379
380
            if (!isset($_POST['name'])) {
381
                $_POST['name'] = $_REQUEST['schema'];
382
            }
383
384
            if (!isset($_POST['owner'])) {
385
                $_POST['owner'] = $schema->fields['ownername'];
386
            }
387
388
            echo '<form action="'.\SUBFOLDER.'/src/views/schemas.php" method="post">'."\n";
389
            echo "<table>\n";
390
391
            echo "\t<tr>\n";
392
            echo "\t\t<th class=\"data left required\">{$lang['strname']}</th>\n";
393
            echo "\t\t<td class=\"data1\">";
394
            echo "\t\t\t<input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"",
395
            htmlspecialchars($_POST['name']), "\" />\n";
396
            echo "\t\t</td>\n";
397
            echo "\t</tr>\n";
398
399
            if ($data->hasAlterSchemaOwner()) {
400
                $users = $data->getUsers();
401
                echo "<tr><th class=\"data left required\">{$lang['strowner']}</th>\n";
402
                echo '<td class="data2"><select name="owner">';
403
                while (!$users->EOF) {
404
                    $uname = $users->fields['usename'];
405
                    echo '<option value="', htmlspecialchars($uname), '"',
406
                    ($uname == $_POST['owner']) ? ' selected="selected"' : '', '>', htmlspecialchars($uname), "</option>\n";
407
                    $users->moveNext();
408
                }
409
                echo "</select></td></tr>\n";
410
            } else {
411
                echo "<input name=\"owner\" value=\"{$_POST['owner']}\" type=\"hidden\" />";
412
            }
413
414
            echo "\t<tr>\n";
415
            echo "\t\t<th class=\"data\">{$lang['strcomment']}</th>\n";
416
            echo "\t\t<td class=\"data1\"><textarea cols=\"32\" rows=\"3\" name=\"comment\">", htmlspecialchars($_POST['comment']), "</textarea></td>\n";
417
            echo "\t</tr>\n";
418
            echo "</table>\n";
419
            echo "<p><input type=\"hidden\" name=\"action\" value=\"alter\" />\n";
420
            echo '<input type="hidden" name="schema" value="', htmlspecialchars($_POST['schema']), "\" />\n";
421
            echo $this->misc->form;
422
            echo "<input type=\"submit\" name=\"alter\" value=\"{$lang['stralter']}\" />\n";
423
            echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n";
424
            echo "</form>\n";
425
        } else {
426
            echo "<p>{$lang['strnodata']}</p>\n";
427
        }
428
    }
429
430
    /**
431
     * Save the form submission containing changes to a schema.
432
     *
433
     * @param mixed $msg
1 ignored issue
show
Missing parameter comment
Loading history...
434
     */
435
    public function doSaveAlter($msg = '')
436
    {
437
        $lang = $this->lang;
438
        $data = $this->misc->getDatabaseAccessor();
439
440
        $status = $data->updateSchema($_POST['schema'], $_POST['comment'], $_POST['name'], $_POST['owner']);
441
        if (0 == $status) {
442
            $this->misc->setReloadBrowser(true);
443
            $this->doDefault($lang['strschemaaltered']);
444
        } else {
445
            $this->doAlter($lang['strschemaalteredbad']);
446
        }
447
    }
448
449
    /**
450
     * Show confirmation of drop and perform actual drop.
451
     *
452
     * @param mixed $confirm
1 ignored issue
show
Missing parameter comment
Loading history...
453
     */
454
    public function doDrop($confirm)
455
    {
456
        $lang = $this->lang;
457
        $data = $this->misc->getDatabaseAccessor();
458
459
        if (empty($_REQUEST['nsp']) && empty($_REQUEST['ma'])) {
460
            return $this->doDefault($lang['strspecifyschematodrop']);
461
        }
462
463
        if ($confirm) {
464
            $this->printTrail('schema');
465
            $this->printTitle($lang['strdrop'], 'pg.schema.drop');
466
467
            echo '<form action="'.\SUBFOLDER.'/src/views/schemas.php" method="post">'."\n";
468
            //If multi drop
469
            if (isset($_REQUEST['ma'])) {
470
                foreach ($_REQUEST['ma'] as $v) {
471
                    $a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES));
472
                    echo '<p>', sprintf($lang['strconfdropschema'], $this->misc->printVal($a['nsp'])), "</p>\n";
473
                    echo '<input type="hidden" name="nsp[]" value="', htmlspecialchars($a['nsp']), "\" />\n";
474
                }
475
            } else {
476
                echo '<p>', sprintf($lang['strconfdropschema'], $this->misc->printVal($_REQUEST['nsp'])), "</p>\n";
477
                echo '<input type="hidden" name="nsp" value="', htmlspecialchars($_REQUEST['nsp']), "\" />\n";
478
            }
479
480
            echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n";
481
            echo "<p><input type=\"hidden\" name=\"action\" value=\"drop\" />\n";
482
            echo '<input type="hidden" name="database" value="', htmlspecialchars($_REQUEST['database']), "\" />\n";
483
            echo $this->misc->form;
484
            echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n";
485
            echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n";
486
            echo "</form>\n";
487
        } else {
488
            if (is_array($_POST['nsp'])) {
489
                $msg    = '';
490
                $status = $data->beginTransaction();
491
                if (0 == $status) {
492
                    foreach ($_POST['nsp'] as $s) {
493
                        $status = $data->dropSchema($s, isset($_POST['cascade']));
494
                        if (0 == $status) {
495
                            $msg .= sprintf('%s: %s<br />', htmlentities($s, ENT_QUOTES, 'UTF-8'), $lang['strschemadropped']);
496
                        } else {
497
                            $data->endTransaction();
498
                            $this->doDefault(sprintf('%s%s: %s<br />', $msg, htmlentities($s, ENT_QUOTES, 'UTF-8'), $lang['strschemadroppedbad']));
499
500
                            return;
501
                        }
502
                    }
503
                }
504
                if (0 == $data->endTransaction()) {
505
                    // Everything went fine, back to the Default page....
506
                    $this->misc->setReloadBrowser(true);
507
                    $this->doDefault($msg);
508
                } else {
509
                    $this->doDefault($lang['strschemadroppedbad']);
510
                }
511
            } else {
512
                $status = $data->dropSchema($_POST['nsp'], isset($_POST['cascade']));
513
                if (0 == $status) {
514
                    $this->misc->setReloadBrowser(true);
515
                    $this->doDefault($lang['strschemadropped']);
516
                } else {
517
                    $this->doDefault($lang['strschemadroppedbad']);
518
                }
519
            }
520
        }
521
    }
522
523
    /**
524
     * Displays options for database download.
525
     *
526
     * @param mixed $msg
1 ignored issue
show
Missing parameter comment
Loading history...
527
     */
528
    public function doExport($msg = '')
529
    {
530
        $lang = $this->lang;
531
        $data = $this->misc->getDatabaseAccessor();
532
533
        $this->printTrail('schema');
534
        $this->printTabs('schema', 'export');
535
        $this->printMsg($msg);
536
537
        echo '<form action="'.\SUBFOLDER.'/src/views/dbexport.php" method="post">'."\n";
538
539
        echo "<table>\n";
540
        echo "<tr><th class=\"data\">{$lang['strformat']}</th><th class=\"data\" colspan=\"2\">{$lang['stroptions']}</th></tr>\n";
541
        // Data only
542
        echo '<tr><th class="data left" rowspan="2">';
543
        echo "<input type=\"radio\" id=\"what1\" name=\"what\" value=\"dataonly\" checked=\"checked\" /><label for=\"what1\">{$lang['strdataonly']}</label></th>\n";
544
        echo "<td>{$lang['strformat']}</td>\n";
545
        echo "<td><select name=\"d_format\">\n";
546
        echo "<option value=\"copy\">COPY</option>\n";
547
        echo "<option value=\"sql\">SQL</option>\n";
548
        echo "</select>\n</td>\n</tr>\n";
549
        echo "<tr><td><label for=\"d_oids\">{$lang['stroids']}</label></td><td><input type=\"checkbox\" id=\"d_oids\" name=\"d_oids\" /></td>\n</tr>\n";
550
        // Structure only
551
        echo "<tr><th class=\"data left\"><input type=\"radio\" id=\"what2\" name=\"what\" value=\"structureonly\" /><label for=\"what2\">{$lang['strstructureonly']}</label></th>\n";
552
        echo "<td><label for=\"s_clean\">{$lang['strdrop']}</label></td><td><input type=\"checkbox\" id=\"s_clean\" name=\"s_clean\" /></td>\n</tr>\n";
553
        // Structure and data
554
        echo '<tr><th class="data left" rowspan="3">';
555
        echo "<input type=\"radio\" id=\"what3\" name=\"what\" value=\"structureanddata\" /><label for=\"what3\">{$lang['strstructureanddata']}</label></th>\n";
556
        echo "<td>{$lang['strformat']}</td>\n";
557
        echo "<td><select name=\"sd_format\">\n";
558
        echo "<option value=\"copy\">COPY</option>\n";
559
        echo "<option value=\"sql\">SQL</option>\n";
560
        echo "</select>\n</td>\n</tr>\n";
561
        echo "<tr><td><label for=\"sd_clean\">{$lang['strdrop']}</label></td><td><input type=\"checkbox\" id=\"sd_clean\" name=\"sd_clean\" /></td>\n</tr>\n";
562
        echo "<tr><td><label for=\"sd_oids\">{$lang['stroids']}</label></td><td><input type=\"checkbox\" id=\"sd_oids\" name=\"sd_oids\" /></td>\n</tr>\n";
563
        echo "</table>\n";
564
565
        echo "<h3>{$lang['stroptions']}</h3>\n";
566
        echo "<p><input type=\"radio\" id=\"output1\" name=\"output\" value=\"show\" checked=\"checked\" /><label for=\"output1\">{$lang['strshow']}</label>\n";
567
        echo "<br/><input type=\"radio\" id=\"output2\" name=\"output\" value=\"download\" /><label for=\"output2\">{$lang['strdownload']}</label>\n";
568
        // MSIE cannot download gzip in SSL mode - it's just broken
569
        if (!(strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE') && isset($_SERVER['HTTPS']))) {
570
            echo "<br /><input type=\"radio\" id=\"output3\" name=\"output\" value=\"gzipped\" /><label for=\"output3\">{$lang['strdownloadgzipped']}</label>\n";
571
        }
572
        echo "</p>\n";
573
        echo "<p><input type=\"hidden\" name=\"action\" value=\"export\" />\n";
574
        echo "<input type=\"hidden\" name=\"subject\" value=\"schema\" />\n";
575
        echo '<input type="hidden" name="database" value="', htmlspecialchars($_REQUEST['database']), "\" />\n";
576
        echo '<input type="hidden" name="schema" value="', htmlspecialchars($_REQUEST['schema']), "\" />\n";
577
        echo $this->misc->form;
578
        echo "<input type=\"submit\" value=\"{$lang['strexport']}\" /></p>\n";
579
        echo "</form>\n";
580
    }
581
}
582