Test Failed
Pull Request — develop (#380)
by Felipe
04:11
created

ViewsController   A

Complexity

Total Complexity 41

Size/Duplication

Total Lines 440
Duplicated Lines 0 %

Importance

Changes 11
Bugs 1 Features 2
Metric Value
eloc 255
c 11
b 1
f 2
dl 0
loc 440
rs 9.1199
wmc 41

How to fix   Complexity   

Complex Class

Complex classes like ViewsController often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ViewsController, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * PHPPgAdmin 6.1.3
5
 */
6
7
namespace PHPPgAdmin\Controller;
8
9
use PHPPgAdmin\Decorators\Decorator;
10
use PHPPgAdmin\Traits\ViewsMatviewsTrait;
11
12
/**
13
 * Base controller class.
14
 */
15
class ViewsController extends BaseController
16
{
17
    use ViewsMatviewsTrait;
18
19
    public $table_place = 'views-views';
20
21
    public $controller_title = 'strviews';
22
23
    // this member variable is view for views and matview for materialized views
24
    public $keystring = 'view';
25
26
    /**
27
     * Default method to render the controller according to the action parameter.
28
     */
29
    public function render()
30
    {
31
        if ('tree' === $this->action) {
32
            return $this->doTree();
33
        }
34
35
        if ('subtree' === $this->action) {
36
            return $this->doSubTree();
37
        }
38
39
        $this->printHeader();
40
        $this->printBody();
41
42
        switch ($this->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(false);
60
                }
61
62
                break;
63
            case 'wiz_create':
64
                $this->doWizardCreate();
65
66
                break;
67
            case 'set_params_create':
68
                if (null !== $this->getPostParam('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 (null !== $this->getPostParam('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
100
            default:
101
                $this->doDefault();
102
103
                break;
104
        }
105
106
        return $this->printFooter();
107
    }
108
109
    /**
110
     * Show default list of views in the database.
111
     *
112
     * @param mixed $msg
113
     */
114
    public function doDefault($msg = ''): void
115
    {
116
        $data = $this->misc->getDatabaseAccessor();
117
118
        $this->printTrail('schema');
119
        $this->printTabs('schema', 'views');
120
        $this->printMsg($msg);
121
122
        $views = $data->getViews();
123
124
        $columns = [
125
            $this->keystring => [
126
                'title' => $this->lang['strview'],
127
                'field' => Decorator::field('relname'),
128
                'url' => \containerInstance()->getDestinationWithLastTab('view'),
129
                    '/redirect/view?%s&amp;',
130
                    $this->misc->href
131
                ),
0 ignored issues
show
Bug introduced by
A parse error occurred: Syntax error, unexpected ')', expecting ',' or ']' on line 131 at column 16
Loading history...
132
                'vars' => [$this->keystring => 'relname'],
133
            ],
134
            'owner' => [
135
                'title' => $this->lang['strowner'],
136
                'field' => Decorator::field('relowner'),
137
            ],
138
            'actions' => [
139
                'title' => $this->lang['stractions'],
140
            ],
141
            'comment' => [
142
                'title' => $this->lang['strcomment'],
143
                'field' => Decorator::field('relcomment'),
144
            ],
145
        ];
146
147
        $actions = [
148
            'multiactions' => [
149
                'keycols' => [$this->keystring => 'relname'],
150
                'url' => 'views',
151
            ],
152
            'browse' => [
153
                'content' => $this->lang['strbrowse'],
154
                'attr' => [
155
                    'href' => [
156
                        'url' => 'display',
157
                        'urlvars' => [
158
                            'action' => 'confselectrows',
159
                            'subject' => $this->keystring,
160
                            'return' => 'schema',
161
                            $this->keystring => Decorator::field('relname'),
162
                        ],
163
                    ],
164
                ],
165
            ],
166
            'select' => [
167
                'content' => $this->lang['strselect'],
168
                'attr' => [
169
                    'href' => [
170
                        'url' => 'views',
171
                        'urlvars' => [
172
                            'action' => 'confselectrows',
173
                            $this->keystring => 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'    => $this->lang['strinsert'],
182
            //                'url'    => "views?action=confinsertrow&amp;{$this->misc->href}&amp;",
183
            //                'vars'    => array($this->keystring => 'relname'),
184
            //            ),
185
186
            'alter' => [
187
                'content' => $this->lang['stralter'],
188
                'attr' => [
189
                    'href' => [
190
                        'url' => 'viewproperties',
191
                        'urlvars' => [
192
                            'action' => 'confirm_alter',
193
                            $this->keystring => Decorator::field('relname'),
194
                        ],
195
                    ],
196
                ],
197
            ],
198
            'drop' => [
199
                'multiaction' => 'confirm_drop',
200
                'content' => $this->lang['strdrop'],
201
                'attr' => [
202
                    'href' => [
203
                        'url' => 'views',
204
                        'urlvars' => [
205
                            'action' => 'confirm_drop',
206
                            $this->keystring => Decorator::field('relname'),
207
                        ],
208
                    ],
209
                ],
210
            ],
211
        ];
212
213
        echo $this->printTable($views, $columns, $actions, $this->table_place, $this->lang['strnoviews']);
214
215
        $navlinks = [
216
            'create' => [
217
                'attr' => [
218
                    'href' => [
219
                        'url' => 'views',
220
                        'urlvars' => [
221
                            'action' => 'create',
222
                            'server' => $_REQUEST['server'],
223
                            'database' => $_REQUEST['database'],
224
                            'schema' => $_REQUEST['schema'],
225
                        ],
226
                    ],
227
                ],
228
                'content' => $this->lang['strcreateview'],
229
            ],
230
            'createwiz' => [
231
                'attr' => [
232
                    'href' => [
233
                        'url' => 'views',
234
                        'urlvars' => [
235
                            'action' => 'wiz_create',
236
                            'server' => $_REQUEST['server'],
237
                            'database' => $_REQUEST['database'],
238
                            'schema' => $_REQUEST['schema'],
239
                        ],
240
                    ],
241
                ],
242
                'content' => $this->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
     * @return \Slim\Http\Response|string
252
     */
253
    public function doTree()
254
    {
255
        $data = $this->misc->getDatabaseAccessor();
256
257
        $views = $data->getViews();
258
259
        $reqvars = $this->misc->getRequestVars($this->keystring);
260
261
        $attrs = [
262
            'text' => Decorator::field('relname'),
263
            'icon' => 'View',
264
            'iconAction' => Decorator::url('display', $reqvars, [$this->keystring => Decorator::field('relname')]),
265
            'toolTip' => Decorator::field('relcomment'),
266
            'action' => Decorator::redirecturl('redirect', $reqvars, [$this->keystring => Decorator::field('relname')]),
267
            'branch' => Decorator::url('views', $reqvars, ['action' => 'subtree', $this->keystring => Decorator::field('relname')]),
268
        ];
269
270
        return $this->printTree($views, $attrs, 'views');
271
    }
272
273
    /**
274
     * Show confirmation of drop and perform actual drop.
275
     *
276
     * @param mixed $confirm
277
     */
278
    public function doDrop($confirm)
279
    {
280
        $data = $this->misc->getDatabaseAccessor();
281
282
        if (empty($_REQUEST['view']) && empty($_REQUEST['ma'])) {
283
            return $this->doDefault($this->lang['strspecifyviewtodrop']);
284
        }
285
286
        if ($confirm) {
287
            $this->printTrail('view');
288
            $this->printTitle($this->lang['strdrop'], 'pg.view.drop');
289
290
            echo '<form action="' . \containerInstance()->subFolder . '/src/views/views" method="post">' . \PHP_EOL;
291
292
            //If multi drop
293
            if (isset($_REQUEST['ma'])) {
294
                foreach ($_REQUEST['ma'] as $v) {
295
                    $a = \unserialize(\htmlspecialchars_decode($v, \ENT_QUOTES));
296
                    echo '<p>', \sprintf(
297
                        $this->lang['strconfdropview'],
298
                        $this->misc->printVal($a['view'])
299
                    ), '</p>' . \PHP_EOL;
300
                    echo '<input type="hidden" name="view[]" value="', \htmlspecialchars($a['view']), '" />' . \PHP_EOL;
301
                }
302
            } else {
303
                echo '<p>', \sprintf(
304
                    $this->lang['strconfdropview'],
305
                    $this->misc->printVal($_REQUEST['view'])
306
                ), '</p>' . \PHP_EOL;
307
                echo '<input type="hidden" name="view" value="', \htmlspecialchars($_REQUEST['view']), '" />' . \PHP_EOL;
308
            }
309
310
            echo '<input type="hidden" name="action" value="drop" />' . \PHP_EOL;
311
312
            echo $this->view->form;
313
            echo \sprintf(
314
                '<p><input type="checkbox" id="cascade" name="cascade" /> <label for="cascade">%s</label></p>',
315
                $this->lang['strcascade']
316
            ) . \PHP_EOL;
317
            echo \sprintf(
318
                '<input type="submit" name="drop" value="%s" />',
319
                $this->lang['strdrop']
320
            ) . \PHP_EOL;
321
            echo \sprintf(
322
                '<input type="submit" name="cancel" value="%s" />',
323
                $this->lang['strcancel']
324
            ) . \PHP_EOL;
325
            echo '</form>' . \PHP_EOL;
326
        } else {
327
            if (\is_array($_POST['view'])) {
328
                $msg = '';
329
                $status = $data->beginTransaction();
330
331
                if (0 === $status) {
332
                    foreach ($_POST['view'] as $s) {
333
                        $status = $data->dropView($s, isset($_POST['cascade']));
334
335
                        if (0 === $status) {
336
                            $msg .= \sprintf(
337
                                '%s: %s<br />',
338
                                \htmlentities($s, \ENT_QUOTES, 'UTF-8'),
339
                                $this->lang['strviewdropped']
340
                            );
341
                        } else {
342
                            $data->endTransaction();
343
                            $this->doDefault(\sprintf(
344
                                '%s%s: %s<br />',
345
                                $msg,
346
                                \htmlentities($s, \ENT_QUOTES, 'UTF-8'),
347
                                $this->lang['strviewdroppedbad']
348
                            ));
349
350
                            return;
351
                        }
352
                    }
353
                }
354
355
                if (0 === $data->endTransaction()) {
356
                    // Everything went fine, back to the Default page....
357
                    $this->view->setReloadBrowser(true);
358
                    $this->doDefault($msg);
359
                } else {
360
                    $this->doDefault($this->lang['strviewdroppedbad']);
361
                }
362
            } else {
363
                $status = $data->dropView($_POST['view'], isset($_POST['cascade']));
364
365
                if (0 === $status) {
366
                    $this->view->setReloadBrowser(true);
367
                    $this->doDefault($this->lang['strviewdropped']);
368
                } else {
369
                    $this->doDefault($this->lang['strviewdroppedbad']);
370
                }
371
            }
372
        }
373
    }
374
375
    /**
376
     * Sets up choices for table linkage, and which fields to select for the view we're creating.
377
     *
378
     * @param mixed $msg
379
     */
380
    public function doSetParamsCreate($msg = '')
381
    {
382
        // Check that they've chosen tables for the view definition
383
        if (!isset($_POST['formTables'])) {
384
            return $this->doWizardCreate($this->lang['strviewneedsdef']);
385
        }
386
        // Initialise variables
387
        $this->coalesceArr($_REQUEST, 'formView', '');
388
389
        $this->coalesceArr($_REQUEST, 'formComment', '');
390
391
        $this->printTrail('schema');
392
        $this->printTitle($this->lang['strcreateviewwiz'], 'pg.view.create');
393
        $this->printMsg($msg);
394
395
        $this->printParamsCreateForm();
396
    }
397
398
    /**
399
     * Display a wizard where they can enter a new view.
400
     *
401
     * @param mixed $msg
402
     */
403
    public function doWizardCreate($msg = ''): void
404
    {
405
        $this->printTrail('schema');
406
        $this->printTitle($this->lang['strcreateviewwiz'], 'pg.view.create');
407
        $this->printMsg($msg);
408
409
        $this->printWizardCreateForm();
410
    }
411
412
    /**
413
     * Displays a screen where they can enter a new view.
414
     *
415
     * @param mixed $msg
416
     */
417
    public function doCreate($msg = ''): void
418
    {
419
        $data = $this->misc->getDatabaseAccessor();
420
421
        $this->coalesceArr($_REQUEST, 'formView', '');
422
423
        if (!isset($_REQUEST['formDefinition'])) {
424
            if (isset($_SESSION['sqlquery'])) {
425
                $_REQUEST['formDefinition'] = $_SESSION['sqlquery'];
426
            } else {
427
                $_REQUEST['formDefinition'] = 'SELECT ';
428
            }
429
        }
430
        $this->coalesceArr($_REQUEST, 'formComment', '');
431
432
        $this->printTrail('schema');
433
        $this->printTitle($this->lang['strcreateview'], 'pg.view.create');
434
        $this->printMsg($msg);
435
436
        echo '<form action="' . \containerInstance()->subFolder . \sprintf(
437
            '/src/views/%s" method="post">',
438
            $this->view_name
439
        ) . \PHP_EOL;
440
        echo '<table style="width: 100%">' . \PHP_EOL;
441
        echo \sprintf(
442
            '	<tr>
443
		<th class="data left required">%s</th>',
444
            $this->lang['strname']
445
        ) . \PHP_EOL;
446
        echo \sprintf(
447
            '	<td class="data1"><input name="formView" size="32" maxlength="%s" value="',
448
            $data->_maxNameLen
449
        ),
450
        \htmlspecialchars($_REQUEST['formView']), "\" /></td>\n\t</tr>" . \PHP_EOL;
451
        echo \sprintf(
452
            '	<tr>
453
		<th class="data left required">%s</th>',
454
            $this->lang['strdefinition']
455
        ) . \PHP_EOL;
456
        echo "\t<td class=\"data1\"><textarea style=\"width:100%;\" rows=\"10\" cols=\"50\" name=\"formDefinition\">",
457
        \htmlspecialchars($_REQUEST['formDefinition']), "</textarea></td>\n\t</tr>" . \PHP_EOL;
458
        echo \sprintf(
459
            '	<tr>
460
		<th class="data left">%s</th>',
461
            $this->lang['strcomment']
462
        ) . \PHP_EOL;
463
        echo "\t\t<td class=\"data1\"><textarea name=\"formComment\" rows=\"3\" cols=\"32\">",
464
        \htmlspecialchars($_REQUEST['formComment']), "</textarea></td>\n\t</tr>" . \PHP_EOL;
465
        echo '</table>' . \PHP_EOL;
466
        echo '<p><input type="hidden" name="action" value="save_create" />' . \PHP_EOL;
467
        echo $this->view->form;
468
        echo \sprintf(
469
            '<input type="submit" value="%s" />',
470
            $this->lang['strcreate']
471
        ) . \PHP_EOL;
472
        echo \sprintf(
473
            '<input type="submit" name="cancel" value="%s"  /></p>%s',
474
            $this->lang['strcancel'],
475
            \PHP_EOL
476
        );
477
        echo '</form>' . \PHP_EOL;
478
    }
479
480
    /**
481
     * Actually creates the new view in the database.
482
     */
483
    public function doSaveCreate(): void
484
    {
485
        $data = $this->misc->getDatabaseAccessor();
486
487
        // Check that they've given a name and a definition
488
        if ('' === $_POST['formView']) {
489
            $this->doCreate($this->lang['strviewneedsname']);
490
        } elseif ('' === $_POST['formDefinition']) {
491
            $this->doCreate($this->lang['strviewneedsdef']);
492
        } else {
493
            $status = $data->createView($_POST['formView'], $_POST['formDefinition'], false, $_POST['formComment']);
494
495
            if (0 === $status) {
496
                $this->view->setReloadBrowser(true);
497
                $this->doDefault($this->lang['strviewcreated']);
498
            } else {
499
                $this->doCreate($this->lang['strviewcreatedbad']);
500
            }
501
        }
502
    }
503
}
504