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

MaterializedviewsController::doDefault()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 133
Code Lines 83

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 83
nc 1
nop 1
dl 0
loc 133
rs 8.2857
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
0 ignored issues
show
Coding Style introduced by
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
 */
5 ignored issues
show
Coding Style introduced by
Missing @category tag in class comment
Loading history...
Coding Style introduced by
Missing @package tag in class comment
Loading history...
Coding Style introduced by
Missing @author tag in class comment
Loading history...
Coding Style introduced by
Missing @license tag in class comment
Loading history...
Coding Style introduced by
Missing @link tag in class comment
Loading history...
14
class MaterializedviewsController extends BaseController
15
{
16
    public $script          = 'materializedviews.php';
17
    public $controller_name = 'MaterializedviewsController';
18
    public $table_place     = 'matviews-matviews';
19
20
    /**
21
     * Default method to render the controller according to the action parameter.
22
     */
23
    public function render()
24
    {
25
        $conf = $this->conf;
0 ignored issues
show
Unused Code introduced by
The assignment to $conf is dead and can be removed.
Loading history...
26
27
        $lang   = $this->lang;
28
        $action = $this->action;
29
30
        if ('tree' == $action) {
31
            return $this->doTree();
32
        }
33
        if ('subtree' == $action) {
34
            return $this->doSubTree();
35
        }
36
37
        $data = $this->misc->getDatabaseAccessor();
0 ignored issues
show
Unused Code introduced by
The assignment to $data is dead and can be removed.
Loading history...
38
39
        $this->printHeader('M '.$lang['strviews']);
40
        $this->printBody();
41
42
        switch ($action) {
43
            case 'selectrows':
44
                if (!isset($_REQUEST['cancel'])) {
45
                    $this->doSelectRows(false);
46
                } else {
47
                    $this->doDefault();
48
                }
49
50
                break;
51
            case 'confselectrows':
52
                $this->doSelectRows(true);
53
54
                break;
55
            case 'save_create_wiz':
56
                if (isset($_REQUEST['cancel'])) {
57
                    $this->doDefault();
58
                } else {
59
                    $this->doSaveCreateWiz();
60
                }
61
62
                break;
63
            case 'wiz_create':
64
                $this->doWizardCreate();
65
66
                break;
67
            case 'set_params_create':
68
                if (isset($_POST['cancel'])) {
69
                    $this->doDefault();
70
                } else {
71
                    $this->doSetParamsCreate();
72
                }
73
74
                break;
75
            case 'save_create':
76
                if (isset($_REQUEST['cancel'])) {
77
                    $this->doDefault();
78
                } else {
79
                    $this->doSaveCreate();
80
                }
81
82
                break;
83
            case 'create':
84
                $this->doCreate();
85
86
                break;
87
            case 'drop':
88
                if (isset($_POST['drop'])) {
89
                    $this->doDrop(false);
90
                } else {
91
                    $this->doDefault();
92
                }
93
94
                break;
95
            case 'confirm_drop':
96
                $this->doDrop(true);
97
98
                break;
99
            default:
100
                $this->doDefault();
101
102
                break;
103
        }
104
105
        $this->printFooter();
106
    }
107
108
    /**
109
     * Show default list of views in the database.
110
     *
111
     * @param mixed $msg
1 ignored issue
show
Coding Style introduced by
Missing parameter comment
Loading history...
112
     */
113
    public function doDefault($msg = '')
114
    {
115
        $conf = $this->conf;
116
117
        $lang = $this->lang;
118
        $data = $this->misc->getDatabaseAccessor();
119
120
        $this->printTrail('schema');
121
        $this->printTabs('schema', 'matviews');
122
        $this->printMsg($msg);
123
124
        //$matviews = $data->getViews();
125
        $matviews = $data->getMaterializedViews();
126
127
        $columns = [
128
            'matview' => [
129
                'title' => 'M '.$lang['strview'],
130
                'field' => Decorator::field('relname'),
131
                'url'   => \SUBFOLDER."/redirect/matview?{$this->misc->href}&amp;",
132
                'vars'  => ['matview' => 'relname'],
133
            ],
134
            'owner' => [
135
                'title' => $lang['strowner'],
136
                'field' => Decorator::field('relowner'),
137
            ],
138
            'actions' => [
139
                'title' => $lang['stractions'],
140
            ],
141
            'comment' => [
142
                'title' => $lang['strcomment'],
143
                'field' => Decorator::field('relcomment'),
144
            ],
145
        ];
146
147
        $actions = [
148
            'multiactions' => [
149
                'keycols' => ['matview' => 'relname'],
150
                'url'     => 'materializedviews.php',
151
            ],
152
            'browse' => [
153
                'content' => $lang['strbrowse'],
154
                'attr'    => [
155
                    'href' => [
156
                        'url'     => 'display.php',
157
                        'urlvars' => [
158
                            'action'  => 'confselectrows',
159
                            'subject' => 'matview',
160
                            'return'  => 'schema',
161
                            'matview' => Decorator::field('relname'),
162
                        ],
163
                    ],
164
                ],
165
            ],
166
            'select' => [
167
                'content' => $lang['strselect'],
168
                'attr'    => [
169
                    'href' => [
170
                        'url'     => 'materializedviews.php',
171
                        'urlvars' => [
172
                            'action'  => 'confselectrows',
173
                            'matview' => Decorator::field('relname'),
174
                        ],
175
                    ],
176
                ],
177
            ],
178
179
            // Insert is possible if the relevant rule for the view has been created.
180
            //            'insert' => array(
181
            //                'title'    => $lang['strinsert'],
182
            //                'url'    => "materializedviews.php?action=confinsertrow&amp;{$this->misc->href}&amp;",
183
            //                'vars'    => array('view' => 'relname'),
184
            //            ),
185
186
            'alter' => [
187
                'content' => $lang['stralter'],
188
                'attr'    => [
189
                    'href' => [
190
                        'url'     => 'materializedviewproperties.php',
191
                        'urlvars' => [
192
                            'action'  => 'confirm_alter',
193
                            'matview' => Decorator::field('relname'),
194
                        ],
195
                    ],
196
                ],
197
            ],
198
            'drop' => [
199
                'multiaction' => 'confirm_drop',
200
                'content'     => $lang['strdrop'],
201
                'attr'        => [
202
                    'href' => [
203
                        'url'     => 'materializedviews.php',
204
                        'urlvars' => [
205
                            'action'  => 'confirm_drop',
206
                            'matview' => Decorator::field('relname'),
207
                        ],
208
                    ],
209
                ],
210
            ],
211
        ];
212
213
        echo $this->printTable($matviews, $columns, $actions, $this->table_place, $lang['strnoviews']);
214
215
        $navlinks = [
216
            'create' => [
217
                'attr' => [
218
                    'href' => [
219
                        'url'     => 'materializedviews.php',
220
                        'urlvars' => [
221
                            'action'   => 'create',
222
                            'server'   => $_REQUEST['server'],
223
                            'database' => $_REQUEST['database'],
224
                            'schema'   => $_REQUEST['schema'],
225
                        ],
226
                    ],
227
                ],
228
                'content' => $lang['strcreateview'],
229
            ],
230
            'createwiz' => [
231
                'attr' => [
232
                    'href' => [
233
                        'url'     => 'materializedviews.php',
234
                        'urlvars' => [
235
                            'action'   => 'wiz_create',
236
                            'server'   => $_REQUEST['server'],
237
                            'database' => $_REQUEST['database'],
238
                            'schema'   => $_REQUEST['schema'],
239
                        ],
240
                    ],
241
                ],
242
                'content' => $lang['strcreateviewwiz'],
243
            ],
244
        ];
245
        $this->printNavLinks($navlinks, $this->table_place, get_defined_vars());
246
    }
247
248
    /**
249
     * Generate XML for the browser tree.
250
     */
251
    public function doTree()
252
    {
253
        $conf = $this->conf;
0 ignored issues
show
Unused Code introduced by
The assignment to $conf is dead and can be removed.
Loading history...
254
255
        $lang = $this->lang;
0 ignored issues
show
Unused Code introduced by
The assignment to $lang is dead and can be removed.
Loading history...
256
        $data = $this->misc->getDatabaseAccessor();
257
258
        $matviews = $data->getMaterializedViews();
259
260
        $reqvars = $this->misc->getRequestVars('matview');
261
262
        $attrs = [
263
            'text'       => Decorator::field('relname'),
264
            'icon'       => 'MView',
265
            'iconAction' => Decorator::url('display.php', $reqvars, ['matview' => Decorator::field('relname')]),
266
            'toolTip'    => Decorator::field('relcomment'),
267
            'action'     => Decorator::redirecturl('redirect.php', $reqvars, ['matview' => Decorator::field('relname')]),
268
            'branch'     => Decorator::url('materializedviews.php', $reqvars, ['action' => 'subtree', 'matview' => Decorator::field('relname')]),
269
        ];
270
271
        return $this->printTree($matviews, $attrs, 'matviews');
272
    }
273
274
    public function doSubTree()
1 ignored issue
show
Coding Style introduced by
Missing function doc comment
Loading history...
275
    {
276
        $conf = $this->conf;
0 ignored issues
show
Unused Code introduced by
The assignment to $conf is dead and can be removed.
Loading history...
277
278
        $lang = $this->lang;
0 ignored issues
show
Unused Code introduced by
The assignment to $lang is dead and can be removed.
Loading history...
279
        $data = $this->misc->getDatabaseAccessor();
0 ignored issues
show
Unused Code introduced by
The assignment to $data is dead and can be removed.
Loading history...
280
281
        $tabs    = $this->misc->getNavTabs('matview');
282
        $items   = $this->adjustTabsForTree($tabs);
283
        $reqvars = $this->misc->getRequestVars('matview');
284
285
        $attrs = [
286
            'text'   => Decorator::field('title'),
287
            'icon'   => Decorator::field('icon'),
288
            'action' => Decorator::actionurl(Decorator::field('url'), $reqvars, Decorator::field('urlvars'), ['matview' => $_REQUEST['matview']]),
289
            'branch' => Decorator::ifempty(
290
                Decorator::field('branch'),
291
                '',
292
                Decorator::url(
293
                    Decorator::field('url'),
294
                    Decorator::field('urlvars'),
295
                    $reqvars,
296
                    [
297
                        'action'  => 'tree',
298
                        'matview' => $_REQUEST['matview'],
299
                    ]
300
                )
301
            ),
302
        ];
303
304
        return $this->printTree($items, $attrs, 'matviews');
305
    }
306
307
    /**
308
     * Ask for select parameters and perform select.
309
     *
310
     * @param mixed $confirm
1 ignored issue
show
Coding Style introduced by
Missing parameter comment
Loading history...
311
     * @param mixed $msg
1 ignored issue
show
Coding Style introduced by
Missing parameter comment
Loading history...
312
     */
313
    public function doSelectRows($confirm, $msg = '')
314
    {
315
        $conf = $this->conf;
0 ignored issues
show
Unused Code introduced by
The assignment to $conf is dead and can be removed.
Loading history...
316
317
        $lang = $this->lang;
318
        $data = $this->misc->getDatabaseAccessor();
319
320
        if ($confirm) {
321
            $this->printTrail('view');
322
            $this->printTabs('matview', 'select');
323
            $this->printMsg($msg);
324
325
            $attrs = $data->getTableAttributes($_REQUEST['matview']);
326
327
            echo '<form action="'.\SUBFOLDER.'/src/views/'.$this->script.'" method="post" id="selectform">';
328
            echo "\n";
329
330
            if ($attrs->recordCount() > 0) {
331
                // JavaScript for select all feature
332
                echo "<script type=\"text/javascript\">\n";
333
                echo "//<![CDATA[\n";
334
                echo "	function selectAll() {\n";
335
                echo "		for (var i=0; i<document.getElementById('selectform').elements.length; i++) {\n";
336
                echo "			var e = document.getElementById('selectform').elements[i];\n";
337
                echo "			if (e.name.indexOf('show') == 0) { \n ";
338
                echo "				e.checked = document.getElementById('selectform').selectall.checked;\n";
339
                echo "			}\n";
340
                echo "		}\n";
341
                echo "	}\n";
342
                echo "//]]>\n";
343
                echo "</script>\n";
344
345
                echo "<table>\n";
346
347
                // Output table header
348
                echo "<tr><th class=\"data\">{$lang['strshow']}</th><th class=\"data\">{$lang['strcolumn']}</th>";
349
                echo "<th class=\"data\">{$lang['strtype']}</th><th class=\"data\">{$lang['stroperator']}</th>";
350
                echo "<th class=\"data\">{$lang['strvalue']}</th></tr>";
351
352
                $i = 0;
353
                while (!$attrs->EOF) {
354
                    $attrs->fields['attnotnull'] = $data->phpBool($attrs->fields['attnotnull']);
355
                    // Set up default value if there isn't one already
356
                    if (!isset($_REQUEST['values'][$attrs->fields['attname']])) {
357
                        $_REQUEST['values'][$attrs->fields['attname']] = null;
358
                    }
359
360
                    if (!isset($_REQUEST['ops'][$attrs->fields['attname']])) {
361
                        $_REQUEST['ops'][$attrs->fields['attname']] = null;
362
                    }
363
364
                    // Continue drawing row
365
                    $id = (0 == ($i % 2) ? '1' : '2');
366
                    echo "<tr class=\"data{$id}\">\n";
367
                    echo '<td style="white-space:nowrap;">';
368
                    echo '<input type="checkbox" name="show[', htmlspecialchars($attrs->fields['attname']), ']"',
369
                    isset($_REQUEST['show'][$attrs->fields['attname']]) ? ' checked="checked"' : '', ' /></td>';
370
                    echo '<td style="white-space:nowrap;">', $this->misc->printVal($attrs->fields['attname']), '</td>';
371
                    echo '<td style="white-space:nowrap;">', $this->misc->printVal($data->formatType($attrs->fields['type'], $attrs->fields['atttypmod'])), '</td>';
372
                    echo '<td style="white-space:nowrap;">';
373
                    echo "<select name=\"ops[{$attrs->fields['attname']}]\">\n";
374
                    foreach (array_keys($data->selectOps) as $v) {
375
                        echo '<option value="', htmlspecialchars($v), '"', ($_REQUEST['ops'][$attrs->fields['attname']] == $v) ? ' selected="selected"' : '',
376
                        '>', htmlspecialchars($v), "</option>\n";
377
                    }
378
                    echo "</select></td>\n";
379
                    echo '<td style="white-space:nowrap;">', $data->printField(
380
                        "values[{$attrs->fields['attname']}]",
381
                        $_REQUEST['values'][$attrs->fields['attname']],
382
                        $attrs->fields['type']
383
                    ), '</td>';
384
                    echo "</tr>\n";
385
                    ++$i;
386
                    $attrs->moveNext();
387
                }
388
                // Select all checkbox
389
                echo "<tr><td colspan=\"5\"><input type=\"checkbox\" id=\"selectall\" name=\"selectall\" accesskey=\"a\" onclick=\"javascript:selectAll()\" /><label for=\"selectall\">{$lang['strselectallfields']}</label></td></tr>";
390
                echo "</table>\n";
391
            } else {
392
                echo "<p>{$lang['strinvalidparam']}</p>\n";
393
            }
394
395
            echo "<p><input type=\"hidden\" name=\"action\" value=\"selectrows\" />\n";
396
            echo '<input type="hidden" name="view" value="', htmlspecialchars($_REQUEST['matview']), "\" />\n";
397
            echo "<input type=\"hidden\" name=\"subject\" value=\"view\" />\n";
398
            echo $this->misc->form;
399
            echo "<input type=\"submit\" name=\"select\" accesskey=\"r\" value=\"{$lang['strselect']}\" />\n";
400
            echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n";
401
            echo "</form>\n";
402
403
            return;
404
        }
405
        if (!isset($_POST['show'])) {
406
            $_POST['show'] = [];
407
        }
408
409
        if (!isset($_POST['values'])) {
410
            $_POST['values'] = [];
411
        }
412
413
        if (!isset($_POST['nulls'])) {
414
            $_POST['nulls'] = [];
415
        }
416
417
        // Verify that they haven't supplied a value for unary operators
418
        foreach ($_POST['ops'] as $k => $v) {
419
            if ('p' == $data->selectOps[$v] && $_POST['values'][$k] != '') {
420
                $this->doSelectRows(true, $lang['strselectunary']);
421
422
                return;
423
            }
424
        }
425
426
        if (0 == sizeof($_POST['show'])) {
427
            return $this->doSelectRows(true, $lang['strselectneedscol']);
428
        }
429
        // Generate query SQL
430
        $query = $data->getSelectSQL($_REQUEST['matview'], array_keys($_POST['show']), $_POST['values'], $_POST['ops']);
431
432
        $_REQUEST['query']  = $query;
433
        $_REQUEST['return'] = 'schema';
434
435
        $this->setNoOutput(true);
436
437
        $display_controller = new DisplayController($this->getContainer());
438
439
        return $display_controller->render();
440
    }
441
442
    /**
443
     * Show confirmation of drop and perform actual drop.
444
     *
445
     * @param mixed $confirm
1 ignored issue
show
Coding Style introduced by
Missing parameter comment
Loading history...
446
     */
447
    public function doDrop($confirm)
448
    {
449
        $conf = $this->conf;
0 ignored issues
show
Unused Code introduced by
The assignment to $conf is dead and can be removed.
Loading history...
450
451
        $lang = $this->lang;
452
        $data = $this->misc->getDatabaseAccessor();
453
454
        if (empty($_REQUEST['matview']) && empty($_REQUEST['ma'])) {
455
            return $this->doDefault($lang['strspecifyviewtodrop']);
456
        }
457
458
        if ($confirm) {
459
            $this->printTrail('getTrail');
460
            $this->printTitle($lang['strdrop'], 'pg.matview.drop');
461
462
            echo '<form action="'.\SUBFOLDER."/src/views/materializedviews.php\" method=\"post\">\n";
463
464
            //If multi drop
465
            if (isset($_REQUEST['ma'])) {
466
                foreach ($_REQUEST['ma'] as $v) {
467
                    $a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES));
468
                    echo '<p>', sprintf($lang['strconfdropview'], $this->misc->printVal($a['view'])), "</p>\n";
469
                    echo '<input type="hidden" name="view[]" value="', htmlspecialchars($a['view']), "\" />\n";
470
                }
471
            } else {
472
                echo '<p>', sprintf($lang['strconfdropview'], $this->misc->printVal($_REQUEST['matview'])), "</p>\n";
473
                echo '<input type="hidden" name="view" value="', htmlspecialchars($_REQUEST['matview']), "\" />\n";
474
            }
475
476
            echo "<input type=\"hidden\" name=\"action\" value=\"drop\" />\n";
477
478
            echo $this->misc->form;
479
            echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$lang['strcascade']}</label></p>\n";
480
            echo "<input type=\"submit\" name=\"drop\" value=\"{$lang['strdrop']}\" />\n";
481
            echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" />\n";
482
            echo "</form>\n";
483
        } else {
484
            if (is_array($_POST['view'])) {
485
                $msg    = '';
486
                $status = $data->beginTransaction();
487
                if (0 == $status) {
488
                    foreach ($_POST['view'] as $s) {
489
                        $status = $data->dropView($s, isset($_POST['cascade']));
490
                        if (0 == $status) {
491
                            $msg .= sprintf('%s: %s<br />', htmlentities($s, ENT_QUOTES, 'UTF-8'), $lang['strviewdropped']);
492
                        } else {
493
                            $data->endTransaction();
494
                            $this->doDefault(sprintf('%s%s: %s<br />', $msg, htmlentities($s, ENT_QUOTES, 'UTF-8'), $lang['strviewdroppedbad']));
495
496
                            return;
497
                        }
498
                    }
499
                }
500
                if (0 == $data->endTransaction()) {
501
                    // Everything went fine, back to the Default page....
502
                    $this->misc->setReloadBrowser(true);
503
                    $this->doDefault($msg);
504
                } else {
505
                    $this->doDefault($lang['strviewdroppedbad']);
506
                }
507
            } else {
508
                $status = $data->dropView($_POST['view'], isset($_POST['cascade']));
509
                if (0 == $status) {
510
                    $this->misc->setReloadBrowser(true);
511
                    $this->doDefault($lang['strviewdropped']);
512
                } else {
513
                    $this->doDefault($lang['strviewdroppedbad']);
514
                }
515
            }
516
        }
517
    }
518
519
    /**
520
     * Sets up choices for table linkage, and which fields to select for the view we're creating.
521
     *
522
     * @param mixed $msg
1 ignored issue
show
Coding Style introduced by
Missing parameter comment
Loading history...
523
     */
524
    public function doSetParamsCreate($msg = '')
525
    {
526
        $conf = $this->conf;
0 ignored issues
show
Unused Code introduced by
The assignment to $conf is dead and can be removed.
Loading history...
527
528
        $lang = $this->lang;
529
        $data = $this->misc->getDatabaseAccessor();
530
531
        // Check that they've chosen tables for the view definition
532
        if (!isset($_POST['formTables'])) {
533
            $this->doWizardCreate($lang['strviewneedsdef']);
534
        } else {
535
            // Initialise variables
536
            if (!isset($_REQUEST['formView'])) {
537
                $_REQUEST['formView'] = '';
538
            }
539
540
            if (!isset($_REQUEST['formComment'])) {
541
                $_REQUEST['formComment'] = '';
542
            }
543
544
            $this->printTrail('schema');
545
            $this->printTitle($lang['strcreateviewwiz'], 'pg.matview.create');
546
            $this->printMsg($msg);
547
548
            $tblCount = sizeof($_POST['formTables']);
549
            //unserialize our schema/table information and store in arrSelTables
550
            for ($i = 0; $i < $tblCount; ++$i) {
551
                $arrSelTables[] = unserialize($_POST['formTables'][$i]);
552
            }
553
554
            $linkCount = $tblCount;
0 ignored issues
show
Unused Code introduced by
The assignment to $linkCount is dead and can be removed.
Loading history...
555
556
            //get linking keys
557
            $rsLinkKeys = $data->getLinkingKeys($arrSelTables);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $arrSelTables does not seem to be defined for all execution paths leading up to this point.
Loading history...
558
            $linkCount  = $rsLinkKeys->recordCount() > $tblCount ? $rsLinkKeys->recordCount() : $tblCount;
559
560
            $arrFields = []; //array that will hold all our table/field names
561
562
            //if we have schemas we need to specify the correct schema for each table we're retrieiving
563
            //with getTableAttributes
564
            $curSchema = $data->_schema;
565
            for ($i = 0; $i < $tblCount; ++$i) {
566
                if ($arrSelTables[$i]['schemaname'] != $data->_schema) {
567
                    $data->setSchema($arrSelTables[$i]['schemaname']);
568
                }
569
570
                $attrs = $data->getTableAttributes($arrSelTables[$i]['tablename']);
571
                while (!$attrs->EOF) {
572
                    $arrFields["{$arrSelTables[$i]['schemaname']}.{$arrSelTables[$i]['tablename']}.{$attrs->fields['attname']}"] = serialize(
573
                        [
574
                            'schemaname' => $arrSelTables[$i]['schemaname'],
575
                            'tablename'  => $arrSelTables[$i]['tablename'],
576
                            'fieldname'  => $attrs->fields['attname'], ]
577
                    );
578
                    $attrs->moveNext();
579
                }
580
581
                $data->setSchema($curSchema);
582
            }
583
            asort($arrFields);
584
585
            echo '<form action="'.\SUBFOLDER."/src/views/materializedviews.php\" method=\"post\">\n";
586
            echo "<table>\n";
587
            echo "<tr><th class=\"data\">{$lang['strviewname']}</th></tr>";
588
            echo "<tr>\n<td class=\"data1\">\n";
589
            // View name
590
            echo '<input name="formView" value="', htmlspecialchars($_REQUEST['formView']), "\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" />\n";
591
            echo "</td>\n</tr>\n";
592
            echo "<tr><th class=\"data\">{$lang['strcomment']}</th></tr>";
593
            echo "<tr>\n<td class=\"data1\">\n";
594
            // View comments
595
            echo '<textarea name="formComment" rows="3" cols="32">',
596
            htmlspecialchars($_REQUEST['formComment']), "</textarea>\n";
597
            echo "</td>\n</tr>\n";
598
            echo "</table>\n";
599
600
            // Output selector for fields to be retrieved from view
601
            echo "<table>\n";
602
            echo "<tr><th class=\"data\">{$lang['strcolumns']}</th></tr>";
603
            echo "<tr>\n<td class=\"data1\">\n";
604
            echo \PHPPgAdmin\XHtml\HTMLController::printCombo($arrFields, 'formFields[]', false, '', true);
605
            echo "</td>\n</tr>";
606
            echo "<tr><td><input type=\"radio\" name=\"dblFldMeth\" id=\"dblFldMeth1\" value=\"rename\" /><label for=\"dblFldMeth1\">{$lang['strrenamedupfields']}</label>";
607
            echo "<br /><input type=\"radio\" name=\"dblFldMeth\" id=\"dblFldMeth2\" value=\"drop\" /><label for=\"dblFldMeth2\">{$lang['strdropdupfields']}</label>";
608
            echo "<br /><input type=\"radio\" name=\"dblFldMeth\" id=\"dblFldMeth3\" value=\"\" checked=\"checked\" /><label for=\"dblFldMeth3\">{$lang['strerrordupfields']}</label></td></tr></table><br />";
609
610
            // Output the Linking keys combo boxes
611
            echo "<table>\n";
612
            echo "<tr><th class=\"data\">{$lang['strviewlink']}</th></tr>";
613
            $rowClass = 'data1';
614
            for ($i = 0; $i < $linkCount; ++$i) {
615
                // Initialise variables
616
                if (!isset($formLink[$i]['operator'])) {
617
                    $formLink[$i]['operator'] = 'INNER JOIN';
618
                }
619
620
                echo "<tr>\n<td class=\"${rowClass}\">\n";
621
622
                if (!$rsLinkKeys->EOF) {
623
                    $curLeftLink  = htmlspecialchars(serialize(['schemaname' => $rsLinkKeys->fields['p_schema'], 'tablename' => $rsLinkKeys->fields['p_table'], 'fieldname' => $rsLinkKeys->fields['p_field']]));
624
                    $curRightLink = htmlspecialchars(serialize(['schemaname' => $rsLinkKeys->fields['f_schema'], 'tablename' => $rsLinkKeys->fields['f_table'], 'fieldname' => $rsLinkKeys->fields['f_field']]));
625
                    $rsLinkKeys->moveNext();
626
                } else {
627
                    $curLeftLink  = '';
628
                    $curRightLink = '';
629
                }
630
631
                echo \PHPPgAdmin\XHtml\HTMLController::printCombo($arrFields, "formLink[${i}][leftlink]", true, $curLeftLink, false);
632
                echo \PHPPgAdmin\XHtml\HTMLController::printCombo($data->joinOps, "formLink[${i}][operator]", true, $formLink[$i]['operator']);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $formLink does not seem to be defined for all execution paths leading up to this point.
Loading history...
633
                echo \PHPPgAdmin\XHtml\HTMLController::printCombo($arrFields, "formLink[${i}][rightlink]", true, $curRightLink, false);
634
                echo "</td>\n</tr>\n";
635
                $rowClass = 'data1' == $rowClass ? 'data2' : 'data1';
636
            }
637
            echo "</table>\n<br />\n";
638
639
            // Build list of available operators (infix only)
640
            $arrOperators = [];
641
            foreach ($data->selectOps as $k => $v) {
642
                if ('i' == $v) {
643
                    $arrOperators[$k] = $k;
644
                }
645
            }
646
647
            // Output additional conditions, note that this portion of the wizard treats the right hand side as literal values
648
            //(not as database objects) so field names will be treated as strings, use the above linking keys section to perform joins
649
            echo "<table>\n";
650
            echo "<tr><th class=\"data\">{$lang['strviewconditions']}</th></tr>";
651
            $rowClass = 'data1';
652
            for ($i = 0; $i < $linkCount; ++$i) {
653
                echo "<tr>\n<td class=\"${rowClass}\">\n";
654
                echo \PHPPgAdmin\XHtml\HTMLController::printCombo($arrFields, "formCondition[${i}][field]");
655
                echo \PHPPgAdmin\XHtml\HTMLController::printCombo($arrOperators, "formCondition[${i}][operator]", false, false);
0 ignored issues
show
Bug introduced by
false of type false is incompatible with the type string expected by parameter $szDefault of PHPPgAdmin\XHtml\HTMLController::printCombo(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

655
                echo \PHPPgAdmin\XHtml\HTMLController::printCombo($arrOperators, "formCondition[${i}][operator]", false, /** @scrutinizer ignore-type */ false);
Loading history...
656
                echo "<input type=\"text\" name=\"formCondition[${i}][txt]\" />\n";
657
                echo "</td>\n</tr>\n";
658
                $rowClass = 'data1' == $rowClass ? 'data2' : 'data1';
659
            }
660
            echo "</table>\n";
661
            echo "<p><input type=\"hidden\" name=\"action\" value=\"save_create_wiz\" />\n";
662
663
            foreach ($arrSelTables as $curTable) {
664
                echo '<input type="hidden" name="formTables[]" value="'.htmlspecialchars(serialize($curTable))."\" />\n";
665
            }
666
667
            echo $this->misc->form;
668
            echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n";
669
            echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n";
670
            echo "</form>\n";
671
        }
672
    }
673
674
    /**
675
     * Display a wizard where they can enter a new view.
676
     *
677
     * @param mixed $msg
1 ignored issue
show
Coding Style introduced by
Missing parameter comment
Loading history...
678
     */
679
    public function doWizardCreate($msg = '')
680
    {
681
        $conf = $this->conf;
0 ignored issues
show
Unused Code introduced by
The assignment to $conf is dead and can be removed.
Loading history...
682
683
        $lang = $this->lang;
684
        $data = $this->misc->getDatabaseAccessor();
685
686
        $tables = $data->getTables(true);
687
688
        $this->printTrail('schema');
689
        $this->printTitle($lang['strcreateviewwiz'], 'pg.matview.create');
690
        $this->printMsg($msg);
691
692
        echo '<form action="'.\SUBFOLDER."/src/views/materializedviews.php\" method=\"post\">\n";
693
        echo "<table>\n";
694
        echo "<tr><th class=\"data\">{$lang['strtables']}</th></tr>";
695
        echo "<tr>\n<td class=\"data1\">\n";
696
697
        $arrTables = [];
698
        while (!$tables->EOF) {
699
            $arrTmp                                                               = [];
700
            $arrTmp['schemaname']                                                 = $tables->fields['nspname'];
701
            $arrTmp['tablename']                                                  = $tables->fields['relname'];
702
            $arrTables[$tables->fields['nspname'].'.'.$tables->fields['relname']] = serialize($arrTmp);
703
            $tables->moveNext();
704
        }
705
        echo \PHPPgAdmin\XHtml\HTMLController::printCombo($arrTables, 'formTables[]', false, '', true);
706
707
        echo "</td>\n</tr>\n";
708
        echo "</table>\n";
709
        echo "<p><input type=\"hidden\" name=\"action\" value=\"set_params_create\" />\n";
710
        echo $this->misc->form;
711
        echo "<input type=\"submit\" value=\"{$lang['strnext']}\" />\n";
712
        echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n";
713
        echo "</form>\n";
714
    }
715
716
    /**
717
     * Displays a screen where they can enter a new view.
718
     *
719
     * @param mixed $msg
1 ignored issue
show
Coding Style introduced by
Missing parameter comment
Loading history...
720
     */
721
    public function doCreate($msg = '')
722
    {
723
        $conf = $this->conf;
0 ignored issues
show
Unused Code introduced by
The assignment to $conf is dead and can be removed.
Loading history...
724
725
        $lang = $this->lang;
726
        $data = $this->misc->getDatabaseAccessor();
727
728
        if (!isset($_REQUEST['formView'])) {
729
            $_REQUEST['formView'] = '';
730
        }
731
732
        if (!isset($_REQUEST['formDefinition'])) {
733
            if (isset($_SESSION['sqlquery'])) {
734
                $_REQUEST['formDefinition'] = $_SESSION['sqlquery'];
735
            } else {
736
                $_REQUEST['formDefinition'] = 'SELECT ';
737
            }
738
        }
739
        if (!isset($_REQUEST['formComment'])) {
740
            $_REQUEST['formComment'] = '';
741
        }
742
743
        $this->printTrail('schema');
744
        $this->printTitle($lang['strcreateview'], 'pg.matview.create');
745
        $this->printMsg($msg);
746
747
        echo '<form action="'.\SUBFOLDER."/src/views/materializedviews.php\" method=\"post\">\n";
748
        echo "<table style=\"width: 100%\">\n";
749
        echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strname']}</th>\n";
750
        echo "\t<td class=\"data1\"><input name=\"formView\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"",
751
        htmlspecialchars($_REQUEST['formView']), "\" /></td>\n\t</tr>\n";
752
        echo "\t<tr>\n\t\t<th class=\"data left required\">{$lang['strdefinition']}</th>\n";
753
        echo "\t<td class=\"data1\"><textarea style=\"width:100%;\" rows=\"10\" cols=\"50\" name=\"formDefinition\">",
754
        htmlspecialchars($_REQUEST['formDefinition']), "</textarea></td>\n\t</tr>\n";
755
        echo "\t<tr>\n\t\t<th class=\"data left\">{$lang['strcomment']}</th>\n";
756
        echo "\t\t<td class=\"data1\"><textarea name=\"formComment\" rows=\"3\" cols=\"32\">",
757
        htmlspecialchars($_REQUEST['formComment']), "</textarea></td>\n\t</tr>\n";
758
        echo "</table>\n";
759
        echo "<p><input type=\"hidden\" name=\"action\" value=\"save_create\" />\n";
760
        echo $this->misc->form;
761
        echo "<input type=\"submit\" value=\"{$lang['strcreate']}\" />\n";
762
        echo "<input type=\"submit\" name=\"cancel\" value=\"{$lang['strcancel']}\" /></p>\n";
763
        echo "</form>\n";
764
    }
765
766
    /**
767
     * Actually creates the new view in the database.
768
     */
769
    public function doSaveCreate()
770
    {
771
        $conf = $this->conf;
0 ignored issues
show
Unused Code introduced by
The assignment to $conf is dead and can be removed.
Loading history...
772
773
        $lang = $this->lang;
774
        $data = $this->misc->getDatabaseAccessor();
775
776
        // Check that they've given a name and a definition
777
        if ('' == $_POST['formView']) {
778
            $this->doCreate($lang['strviewneedsname']);
779
        } elseif ('' == $_POST['formDefinition']) {
780
            $this->doCreate($lang['strviewneedsdef']);
781
        } else {
782
            $status = $data->createView($_POST['formView'], $_POST['formDefinition'], false, $_POST['formComment']);
783
            if (0 == $status) {
784
                $this->misc->setReloadBrowser(true);
785
                $this->doDefault($lang['strviewcreated']);
786
            } else {
787
                $this->doCreate($lang['strviewcreatedbad']);
788
            }
789
        }
790
    }
791
792
    /**
793
     * Actually creates the new wizard view in the database.
794
     */
795
    public function doSaveCreateWiz()
796
    {
797
        $conf = $this->conf;
0 ignored issues
show
Unused Code introduced by
The assignment to $conf is dead and can be removed.
Loading history...
798
799
        $lang = $this->lang;
800
        $data = $this->misc->getDatabaseAccessor();
801
802
        // Check that they've given a name and fields they want to select
803
804
        if (!strlen($_POST['formView'])) {
805
            $this->doSetParamsCreate($lang['strviewneedsname']);
806
        } elseif (!isset($_POST['formFields']) || !count($_POST['formFields'])) {
807
            $this->doSetParamsCreate($lang['strviewneedsfields']);
808
        } else {
809
            $selFields = '';
810
811
            if (!empty($_POST['dblFldMeth'])) {
812
                $tmpHsh = [];
813
            }
814
815
            foreach ($_POST['formFields'] as $curField) {
816
                $arrTmp = unserialize($curField);
817
                $data->fieldArrayClean($arrTmp);
818
                if (!empty($_POST['dblFldMeth'])) {
819
                    // doublon control
820
                    if (empty($tmpHsh[$arrTmp['fieldname']])) {
821
                        // field does not exist
822
                        $selFields .= "\"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\".\"{$arrTmp['fieldname']}\", ";
823
                        $tmpHsh[$arrTmp['fieldname']] = 1;
824
                    } elseif ('rename' == $_POST['dblFldMeth']) {
825
                        // field exist and must be renamed
826
                        ++$tmpHsh[$arrTmp['fieldname']];
827
                        $selFields .= "\"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\".\"{$arrTmp['fieldname']}\" AS \"{$arrTmp['schemaname']}_{$arrTmp['tablename']}_{$arrTmp['fieldname']}{$tmpHsh[$arrTmp['fieldname']]}\", ";
828
                    }
829
                    // field already exist, just ignore this one
830
                } else {
831
                    // no doublon control
832
                    $selFields .= "\"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\".\"{$arrTmp['fieldname']}\", ";
833
                }
834
            }
835
836
            $selFields = substr($selFields, 0, -2);
837
            unset($arrTmp, $tmpHsh);
838
            $linkFields = '';
839
840
            // If we have links, out put the JOIN ... ON statements
841
            if (is_array($_POST['formLink'])) {
842
                // Filter out invalid/blank entries for our links
843
                $arrLinks = [];
844
                foreach ($_POST['formLink'] as $curLink) {
845
                    if (strlen($curLink['leftlink']) && strlen($curLink['rightlink']) && strlen($curLink['operator'])) {
846
                        $arrLinks[] = $curLink;
847
                    }
848
                }
849
                // We must perform some magic to make sure that we have a valid join order
850
                $count       = sizeof($arrLinks);
851
                $arrJoined   = [];
852
                $arrUsedTbls = [];
853
854
                // If we have at least one join condition, output it
855
                if ($count > 0) {
856
                    $j = 0;
857
                    while ($j < $count) {
858
                        foreach ($arrLinks as $curLink) {
859
                            $arrLeftLink  = unserialize($curLink['leftlink']);
860
                            $arrRightLink = unserialize($curLink['rightlink']);
861
                            $data->fieldArrayClean($arrLeftLink);
862
                            $data->fieldArrayClean($arrRightLink);
863
864
                            $tbl1 = "\"{$arrLeftLink['schemaname']}\".\"{$arrLeftLink['tablename']}\"";
865
                            $tbl2 = "\"{$arrRightLink['schemaname']}\".\"{$arrRightLink['tablename']}\"";
866
867
                            if ((!in_array($curLink, $arrJoined, true) && in_array($tbl1, $arrUsedTbls, true)) || !count($arrJoined)) {
868
                                // Make sure for multi-column foreign keys that we use a table alias tables joined to more than once
869
                                // This can (and should be) more optimized for multi-column foreign keys
870
                                $adj_tbl2 = in_array($tbl2, $arrUsedTbls, true) ? "${tbl2} AS alias_ppa_".mktime() : $tbl2;
871
872
                                $linkFields .= strlen($linkFields) ? "{$curLink['operator']} ${adj_tbl2} ON (\"{$arrLeftLink['schemaname']}\".\"{$arrLeftLink['tablename']}\".\"{$arrLeftLink['fieldname']}\" = \"{$arrRightLink['schemaname']}\".\"{$arrRightLink['tablename']}\".\"{$arrRightLink['fieldname']}\") "
873
                                : "${tbl1} {$curLink['operator']} ${adj_tbl2} ON (\"{$arrLeftLink['schemaname']}\".\"{$arrLeftLink['tablename']}\".\"{$arrLeftLink['fieldname']}\" = \"{$arrRightLink['schemaname']}\".\"{$arrRightLink['tablename']}\".\"{$arrRightLink['fieldname']}\") ";
874
875
                                $arrJoined[] = $curLink;
876
                                if (!in_array($tbl1, $arrUsedTbls, true)) {
877
                                    $arrUsedTbls[] = $tbl1;
878
                                }
879
880
                                if (!in_array($tbl2, $arrUsedTbls, true)) {
881
                                    $arrUsedTbls[] = $tbl2;
882
                                }
883
                            }
884
                        }
885
                        ++$j;
886
                    }
887
                }
888
            }
889
890
            //if linkfields has no length then either _POST['formLink'] was not set, or there were no join conditions
891
            //just select from all seleted tables - a cartesian join do a
892
            if (!strlen($linkFields)) {
893
                foreach ($_POST['formTables'] as $curTable) {
894
                    $arrTmp = unserialize($curTable);
895
                    $data->fieldArrayClean($arrTmp);
896
                    $linkFields .= strlen($linkFields) ? ", \"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\"" : "\"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\"";
897
                }
898
            }
899
900
            $addConditions = '';
901
            if (is_array($_POST['formCondition'])) {
902
                foreach ($_POST['formCondition'] as $curCondition) {
903
                    if (strlen($curCondition['field']) && strlen($curCondition['txt'])) {
904
                        $arrTmp = unserialize($curCondition['field']);
905
                        $data->fieldArrayClean($arrTmp);
906
                        $addConditions .= strlen($addConditions) ? " AND \"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\".\"{$arrTmp['fieldname']}\" {$curCondition['operator']} '{$curCondition['txt']}' "
907
                        : " \"{$arrTmp['schemaname']}\".\"{$arrTmp['tablename']}\".\"{$arrTmp['fieldname']}\" {$curCondition['operator']} '{$curCondition['txt']}' ";
908
                    }
909
                }
910
            }
911
912
            $viewQuery = "SELECT ${selFields} FROM ${linkFields} ";
913
914
            //add where from additional conditions
915
            if (strlen($addConditions)) {
916
                $viewQuery .= ' WHERE '.$addConditions;
917
            }
918
919
            $status = $data->createView($_POST['formView'], $viewQuery, false, $_POST['formComment']);
920
            if (0 == $status) {
921
                $this->misc->setReloadBrowser(true);
922
                $this->doDefault($lang['strviewcreated']);
923
            } else {
924
                $this->doSetParamsCreate($lang['strviewcreatedbad']);
925
            }
926
        }
927
    }
928
}
929