TypesController::doCreateComposite()   F
last analyzed

Complexity

Conditions 27
Paths 26

Size

Total Lines 169
Code Lines 117

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 27
eloc 117
c 1
b 0
f 0
nc 26
nop 1
dl 0
loc 169
rs 3.3333

How to fix   Long Method    Complexity   

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
3
/**
4
 * PHPPgAdmin 6.1.3
5
 */
6
7
namespace PHPPgAdmin\Controller;
8
9
use PHPPgAdmin\Decorators\Decorator;
10
11
/**
12
 * Base controller class.
13
 */
14
class TypesController extends BaseController
15
{
16
    public $controller_title = 'strtypes';
17
18
    /**
19
     * Default method to render the controller according to the action parameter.
20
     */
21
    public function render()
22
    {
23
        if ('tree' === $this->action) {
24
            return $this->doTree();
25
        }
26
27
        $this->printHeader();
28
        $this->printBody();
29
30
        switch ($this->action) {
31
            case 'create_comp':
32
                if (null !== $this->getPostParam('cancel')) {
33
                    $this->doDefault();
34
                } else {
35
                    $this->doCreateComposite();
36
                }
37
38
                break;
39
            case 'create_enum':
40
                if (null !== $this->getPostParam('cancel')) {
41
                    $this->doDefault();
42
                } else {
43
                    $this->doCreateEnum();
44
                }
45
46
                break;
47
            case 'save_create':
48
                if (null !== $this->getPostParam('cancel')) {
49
                    $this->doDefault();
50
                } else {
51
                    $this->doSaveCreate();
52
                }
53
54
                break;
55
            case 'create':
56
                $this->doCreate();
57
58
                break;
59
            case 'drop':
60
                if (null !== $this->getPostParam('cancel')) {
61
                    $this->doDefault();
62
                } else {
63
                    $this->doDrop(false);
64
                }
65
66
                break;
67
            case 'confirm_drop':
68
                $this->doDrop(true);
69
70
                break;
71
            case 'properties':
72
                $this->doProperties();
73
74
                break;
75
76
            default:
77
                $this->doDefault();
78
79
                break;
80
        }
81
82
        return $this->printFooter();
83
    }
84
85
    /**
86
     * Show default list of types in the database.
87
     *
88
     * @param mixed $msg
89
     */
90
    public function doDefault($msg = ''): void
91
    {
92
        $data = $this->misc->getDatabaseAccessor();
93
94
        $this->printTrail('schema');
95
        $this->printTabs('schema', 'types');
96
        $this->printMsg($msg);
97
98
        $types = $data->getTypes();
99
100
        $columns = [
101
            'type' => [
102
                'title' => $this->lang['strtype'],
103
                'field' => Decorator::field('typname'),
104
                'url' => "types?action=properties&amp;{$this->misc->href}&amp;",
105
                'vars' => ['type' => 'basename'],
106
            ],
107
            'owner' => [
108
                'title' => $this->lang['strowner'],
109
                'field' => Decorator::field('typowner'),
110
            ],
111
            'flavour' => [
112
                'title' => $this->lang['strflavor'],
113
                'field' => Decorator::field('typtype'),
114
                'type' => 'verbatim',
115
                'params' => [
116
                    'map' => [
117
                        'b' => $this->lang['strbasetype'],
118
                        'c' => $this->lang['strcompositetype'],
119
                        'd' => $this->lang['strdomain'],
120
                        'p' => $this->lang['strpseudotype'],
121
                        'e' => $this->lang['strenum'],
122
                    ],
123
                    'align' => 'center',
124
                ],
125
            ],
126
            'actions' => [
127
                'title' => $this->lang['stractions'],
128
            ],
129
            'comment' => [
130
                'title' => $this->lang['strcomment'],
131
                'field' => Decorator::field('typcomment'),
132
            ],
133
        ];
134
135
        if (!isset($types->fields['typtype'])) {
136
            unset($columns['flavour']);
137
        }
138
139
        $actions = [
140
            'drop' => [
141
                'content' => $this->lang['strdrop'],
142
                'attr' => [
143
                    'href' => [
144
                        'url' => 'types',
145
                        'urlvars' => [
146
                            'action' => 'confirm_drop',
147
                            'type' => Decorator::field('basename'),
148
                        ],
149
                    ],
150
                ],
151
            ],
152
        ];
153
154
        echo $this->printTable($types, $columns, $actions, 'types-types', $this->lang['strnotypes']);
0 ignored issues
show
Bug introduced by
It seems like $types can also be of type integer; however, parameter $tabledata of PHPPgAdmin\Controller\BaseController::printTable() does only seem to accept ADORecordSet|PHPPgAdmin\ArrayRecordSet, maybe add an additional type check? ( Ignorable by Annotation )

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

154
        echo $this->printTable(/** @scrutinizer ignore-type */ $types, $columns, $actions, 'types-types', $this->lang['strnotypes']);
Loading history...
155
156
        $navlinks = [
157
            'create' => [
158
                'attr' => [
159
                    'href' => [
160
                        'url' => 'types',
161
                        'urlvars' => [
162
                            'action' => 'create',
163
                            'server' => $_REQUEST['server'],
164
                            'database' => $_REQUEST['database'],
165
                            'schema' => $_REQUEST['schema'],
166
                        ],
167
                    ],
168
                ],
169
                'content' => $this->lang['strcreatetype'],
170
            ],
171
            'createcomp' => [
172
                'attr' => [
173
                    'href' => [
174
                        'url' => 'types',
175
                        'urlvars' => [
176
                            'action' => 'create_comp',
177
                            'server' => $_REQUEST['server'],
178
                            'database' => $_REQUEST['database'],
179
                            'schema' => $_REQUEST['schema'],
180
                        ],
181
                    ],
182
                ],
183
                'content' => $this->lang['strcreatecomptype'],
184
            ],
185
            'createenum' => [
186
                'attr' => [
187
                    'href' => [
188
                        'url' => 'types',
189
                        'urlvars' => [
190
                            'action' => 'create_enum',
191
                            'server' => $_REQUEST['server'],
192
                            'database' => $_REQUEST['database'],
193
                            'schema' => $_REQUEST['schema'],
194
                        ],
195
                    ],
196
                ],
197
                'content' => $this->lang['strcreateenumtype'],
198
            ],
199
        ];
200
201
        //if (!$data->hasEnumTypes()) {            unset($navlinks['enum']);        }
202
203
        $this->printNavLinks($navlinks, 'types-types', \get_defined_vars());
204
    }
205
206
    /**
207
     * Generate XML for the browser tree.
208
     */
209
    public function doTree()
210
    {
211
        $data = $this->misc->getDatabaseAccessor();
212
213
        $types = $data->getTypes();
214
215
        $reqvars = $this->misc->getRequestVars('type');
216
217
        $attrs = [
218
            'text' => Decorator::field('typname'),
219
            'icon' => 'Type',
220
            'toolTip' => Decorator::field('typcomment'),
221
            'action' => Decorator::actionurl(
222
                'types',
223
                $reqvars,
224
                [
225
                    'action' => 'properties',
226
                    'type' => Decorator::field('basename'),
227
                ]
228
            ),
229
        ];
230
231
        return $this->printTree($types, $attrs, 'types');
0 ignored issues
show
Bug introduced by
It seems like $types can also be of type integer; however, parameter $_treedata of PHPPgAdmin\Controller\BaseController::printTree() does only seem to accept PHPPgAdmin\ADORecordSet|PHPPgAdmin\ArrayRecordSet, maybe add an additional type check? ( Ignorable by Annotation )

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

231
        return $this->printTree(/** @scrutinizer ignore-type */ $types, $attrs, 'types');
Loading history...
232
    }
233
234
    /**
235
     * Show read only properties for a type.
236
     *
237
     * @param mixed $msg
238
     */
239
    public function doProperties($msg = ''): void
240
    {
241
        $data = $this->misc->getDatabaseAccessor();
242
        // Get type (using base name)
243
        $typedata = $data->getType($_REQUEST['type']);
244
245
        $this->printTrail('type');
246
        $this->printTitle($this->lang['strproperties'], 'pg.type');
247
        $this->printMsg($msg);
248
249
        $attPre = static function (&$rowdata) use ($data): void {
250
            $rowdata->fields['+type'] = $data->formatType($rowdata->fields['type'], $rowdata->fields['atttypmod']);
251
        };
252
253
        if (0 < $typedata->recordCount()) {
254
            $vals = false;
255
256
            switch ($typedata->fields['typtype']) {
257
                case 'c':
258
                    $attrs = $data->getTableAttributes($_REQUEST['type']);
259
260
                    $columns = [
261
                        'field' => [
262
                            'title' => $this->lang['strfield'],
263
                            'field' => Decorator::field('attname'),
264
                        ],
265
                        'type' => [
266
                            'title' => $this->lang['strtype'],
267
                            'field' => Decorator::field('+type'),
268
                        ],
269
                        'comment' => [
270
                            'title' => $this->lang['strcomment'],
271
                            'field' => Decorator::field('comment'),
272
                        ],
273
                    ];
274
275
                    $actions = [];
276
277
                    echo $this->printTable($attrs, $columns, $actions, 'types-properties', $this->lang['strnodata'], $attPre);
278
279
                    break;
280
                case 'e':
281
                    $vals = $data->getEnumValues($typedata->fields['typname']);
282
                // no break
283
                default:
284
                    $byval = $data->phpBool($typedata->fields['typbyval']);
285
                    echo '<table>' . \PHP_EOL;
286
                    echo "<tr><th class=\"data left\">{$this->lang['strname']}</th>" . \PHP_EOL;
287
                    echo '<td class="data1">', $this->misc->printVal($typedata->fields['typname']), '</td></tr>' . \PHP_EOL;
288
                    echo "<tr><th class=\"data left\">{$this->lang['strinputfn']}</th>" . \PHP_EOL;
289
                    echo '<td class="data1">', $this->misc->printVal($typedata->fields['typin']), '</td></tr>' . \PHP_EOL;
290
                    echo "<tr><th class=\"data left\">{$this->lang['stroutputfn']}</th>" . \PHP_EOL;
291
                    echo '<td class="data1">', $this->misc->printVal($typedata->fields['typout']), '</td></tr>' . \PHP_EOL;
292
                    echo "<tr><th class=\"data left\">{$this->lang['strlength']}</th>" . \PHP_EOL;
293
                    echo '<td class="data1">', $this->misc->printVal($typedata->fields['typlen']), '</td></tr>' . \PHP_EOL;
294
                    echo "<tr><th class=\"data left\">{$this->lang['strpassbyval']}</th>" . \PHP_EOL;
295
                    echo '<td class="data1">', ($byval) ? $this->lang['stryes'] : $this->lang['strno'], '</td></tr>' . \PHP_EOL;
296
                    echo "<tr><th class=\"data left\">{$this->lang['stralignment']}</th>" . \PHP_EOL;
297
                    echo '<td class="data1">', $this->misc->printVal($typedata->fields['typalign']), '</td></tr>' . \PHP_EOL;
298
299
                    if ($data->hasEnumTypes() && $vals) {
300
                        $vals = $vals->getArray();
301
                        $nbVals = \count($vals);
302
                        echo "<tr>\n\t<th class=\"data left\" rowspan=\"{$nbVals}\">{$this->lang['strenumvalues']}</th>" . \PHP_EOL;
303
                        echo "<td class=\"data2\">{$vals[0]['enumval']}</td></tr>" . \PHP_EOL;
304
305
                        for ($i = 1; $i < $nbVals; ++$i) {
306
                            echo '<td class="data', 2 - ($i % 2), "\">{$vals[$i]['enumval']}</td></tr>" . \PHP_EOL;
307
                        }
308
                    }
309
                    echo '</table>' . \PHP_EOL;
310
            }
311
312
            $this->printNavLinks(['showall' => [
313
                'attr' => [
314
                    'href' => [
315
                        'url' => 'types',
316
                        'urlvars' => [
317
                            'server' => $_REQUEST['server'],
318
                            'database' => $_REQUEST['database'],
319
                            'schema' => $_REQUEST['schema'],
320
                        ],
321
                    ],
322
                ],
323
                'content' => $this->lang['strshowalltypes'],
324
            ]], 'types-properties', \get_defined_vars());
325
        } else {
326
            $this->doDefault($this->lang['strinvalidparam']);
327
        }
328
    }
329
330
    /**
331
     * Show confirmation of drop and perform actual drop.
332
     *
333
     * @param mixed $confirm
334
     */
335
    public function doDrop($confirm): void
336
    {
337
        $data = $this->misc->getDatabaseAccessor();
338
339
        if ($confirm) {
340
            $this->printTrail('type');
341
            $this->printTitle($this->lang['strdrop'], 'pg.type.drop');
342
343
            echo '<p>', \sprintf($this->lang['strconfdroptype'], $this->misc->printVal($_REQUEST['type'])), '</p>' . \PHP_EOL;
344
345
            echo '<form action="' . \containerInstance()->subFolder . '/src/views/types" method="post">' . \PHP_EOL;
346
            echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /> <label for=\"cascade\">{$this->lang['strcascade']}</label></p>" . \PHP_EOL;
347
            echo '<p><input type="hidden" name="action" value="drop" />' . \PHP_EOL;
348
            echo '<input type="hidden" name="type" value="', \htmlspecialchars($_REQUEST['type']), '" />' . \PHP_EOL;
349
            echo $this->view->form;
350
            echo "<input type=\"submit\" name=\"drop\" value=\"{$this->lang['strdrop']}\" />" . \PHP_EOL;
351
            echo \sprintf('<input type="submit" name="cancel" value="%s"  /></p>%s', $this->lang['strcancel'], \PHP_EOL);
352
            echo '</form>' . \PHP_EOL;
353
        } else {
354
            $status = $data->dropType($_POST['type'], isset($_POST['cascade']));
355
356
            if (0 === $status) {
357
                $this->doDefault($this->lang['strtypedropped']);
358
            } else {
359
                $this->doDefault($this->lang['strtypedroppedbad']);
360
            }
361
        }
362
    }
363
364
    /**
365
     * Displays a screen where they can enter a new composite type.
366
     *
367
     * @param mixed $msg
368
     */
369
    public function doCreateComposite($msg = ''): void
370
    {
371
        $data = $this->misc->getDatabaseAccessor();
372
373
        $this->coalesceArr($_REQUEST, 'stage', 1);
374
375
        $this->coalesceArr($_REQUEST, 'name', '');
376
377
        $this->coalesceArr($_REQUEST, 'fields', '');
378
379
        $this->coalesceArr($_REQUEST, 'typcomment', '');
380
381
        switch ($_REQUEST['stage']) {
382
            case 1:
383
                $this->printTrail('type');
384
                $this->printTitle($this->lang['strcreatecomptype'], 'pg.type.create');
385
                $this->printMsg($msg);
386
387
                echo '<form action="' . \containerInstance()->subFolder . '/src/views/types" method="post">' . \PHP_EOL;
388
                echo '<table>' . \PHP_EOL;
389
                echo "\t<tr>\n\t\t<th class=\"data left required\">{$this->lang['strname']}</th>" . \PHP_EOL;
390
                echo "\t\t<td class=\"data\"><input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"",
391
                \htmlspecialchars($_REQUEST['name']), "\" /></td>\n\t</tr>" . \PHP_EOL;
392
                echo "\t<tr>\n\t\t<th class=\"data left required\">{$this->lang['strnumfields']}</th>" . \PHP_EOL;
393
                echo "\t\t<td class=\"data\"><input name=\"fields\" size=\"5\" maxlength=\"{$data->_maxNameLen}\" value=\"",
394
                \htmlspecialchars($_REQUEST['fields']), "\" /></td>\n\t</tr>" . \PHP_EOL;
395
396
                echo "\t<tr>\n\t\t<th class=\"data left\">{$this->lang['strcomment']}</th>" . \PHP_EOL;
397
                echo "\t\t<td><textarea name=\"typcomment\" rows=\"3\" cols=\"32\">",
398
                \htmlspecialchars($_REQUEST['typcomment']), "</textarea></td>\n\t</tr>" . \PHP_EOL;
399
400
                echo '</table>' . \PHP_EOL;
401
                echo '<p><input type="hidden" name="action" value="create_comp" />' . \PHP_EOL;
402
                echo '<input type="hidden" name="stage" value="2" />' . \PHP_EOL;
403
                echo $this->view->form;
404
                echo "<input type=\"submit\" value=\"{$this->lang['strnext']}\" />" . \PHP_EOL;
405
                echo \sprintf('<input type="submit" name="cancel" value="%s"  /></p>%s', $this->lang['strcancel'], \PHP_EOL);
406
                echo '</form>' . \PHP_EOL;
407
408
                break;
409
            case 2:
410
                // Check inputs
411
                $fields = \trim($_REQUEST['fields']);
412
413
                if ('' === \trim($_REQUEST['name'])) {
414
                    $_REQUEST['stage'] = 1;
415
                    $this->doCreateComposite($this->lang['strtypeneedsname']);
416
417
                    return;
418
                }
419
420
                if ('' === $fields || !\is_numeric($fields) || (int) $fields !== $fields || 1 > $fields) {
421
                    $_REQUEST['stage'] = 1;
422
                    $this->doCreateComposite($this->lang['strtypeneedscols']);
423
424
                    return;
425
                }
426
427
                $types = $data->getTypes(true, false, true);
428
429
                $this->printTrail('schema');
430
                $this->printTitle($this->lang['strcreatecomptype'], 'pg.type.create');
431
                $this->printMsg($msg);
432
433
                echo '<form action="' . \containerInstance()->subFolder . '/src/views/types" method="post">' . \PHP_EOL;
434
435
                // Output table header
436
                echo '<table>' . \PHP_EOL;
437
                echo "\t<tr><th colspan=\"2\" class=\"data required\">{$this->lang['strfield']}</th><th colspan=\"2\" class=\"data required\">{$this->lang['strtype']}</th>";
438
                echo "<th class=\"data\">{$this->lang['strlength']}</th><th class=\"data\">{$this->lang['strcomment']}</th></tr>" . \PHP_EOL;
439
440
                for ($i = 0; $i < $_REQUEST['fields']; ++$i) {
441
                    if (!isset($_REQUEST['field'][$i])) {
442
                        $_REQUEST['field'][$i] = '';
443
                    }
444
445
                    if (!isset($_REQUEST['length'][$i])) {
446
                        $_REQUEST['length'][$i] = '';
447
                    }
448
449
                    if (!isset($_REQUEST['colcomment'][$i])) {
450
                        $_REQUEST['colcomment'][$i] = '';
451
                    }
452
453
                    echo "\t<tr>\n\t\t<td>", $i + 1, '.&nbsp;</td>' . \PHP_EOL;
454
                    echo "\t\t<td><input name=\"field[{$i}]\" size=\"16\" maxlength=\"{$data->_maxNameLen}\" value=\"",
455
                    \htmlspecialchars($_REQUEST['field'][$i]), '" /></td>' . \PHP_EOL;
456
                    echo "\t\t<td>\n\t\t\t<select name=\"type[{$i}]\">" . \PHP_EOL;
457
                    $types->moveFirst();
458
459
                    while (!$types->EOF) {
460
                        $typname = $types->fields['typname'];
461
                        echo "\t\t\t\t<option value=\"", \htmlspecialchars($typname), '"',
462
                        (isset($_REQUEST['type'][$i]) && $_REQUEST['type'][$i] === $typname) ? ' selected="selected"' : '', '>',
463
                        $this->misc->printVal($typname), '</option>' . \PHP_EOL;
464
                        $types->moveNext();
465
                    }
466
                    echo "\t\t\t</select>\n\t\t</td>" . \PHP_EOL;
467
468
                    // Output array type selector
469
                    echo "\t\t<td>\n\t\t\t<select name=\"array[{$i}]\">" . \PHP_EOL;
470
                    echo "\t\t\t\t<option value=\"\"", (isset($_REQUEST['array'][$i]) && '' === $_REQUEST['array'][$i]) ? ' selected="selected"' : '', '></option>' . \PHP_EOL;
471
                    echo "\t\t\t\t<option value=\"[]\"", (isset($_REQUEST['array'][$i]) && '[]' === $_REQUEST['array'][$i]) ? ' selected="selected"' : '', '>[ ]</option>' . \PHP_EOL;
472
                    echo "\t\t\t</select>\n\t\t</td>" . \PHP_EOL;
473
474
                    echo "\t\t<td><input name=\"length[{$i}]\" size=\"10\" value=\"",
475
                    \htmlspecialchars($_REQUEST['length'][$i]), '" /></td>' . \PHP_EOL;
476
                    echo "\t\t<td><input name=\"colcomment[{$i}]\" size=\"40\" value=\"",
477
                    \htmlspecialchars($_REQUEST['colcomment'][$i]), "\" /></td>\n\t</tr>" . \PHP_EOL;
478
                }
479
                echo '</table>' . \PHP_EOL;
480
                echo '<p><input type="hidden" name="action" value="create_comp" />' . \PHP_EOL;
481
                echo '<input type="hidden" name="stage" value="3" />' . \PHP_EOL;
482
                echo $this->view->form;
483
                echo '<input type="hidden" name="name" value="', \htmlspecialchars($_REQUEST['name']), '" />' . \PHP_EOL;
484
                echo '<input type="hidden" name="fields" value="', \htmlspecialchars($_REQUEST['fields']), '" />' . \PHP_EOL;
485
                echo '<input type="hidden" name="typcomment" value="', \htmlspecialchars($_REQUEST['typcomment']), '" />' . \PHP_EOL;
486
                echo "<input type=\"submit\" value=\"{$this->lang['strcreate']}\" />" . \PHP_EOL;
487
                echo \sprintf('<input type="submit" name="cancel" value="%s"  /></p>%s', $this->lang['strcancel'], \PHP_EOL);
488
                echo '</form>' . \PHP_EOL;
489
490
                break;
491
            case 3:
492
                // Check inputs
493
                $fields = \trim($_REQUEST['fields']);
494
495
                if ('' === \trim($_REQUEST['name'])) {
496
                    $_REQUEST['stage'] = 1;
497
                    $this->doCreateComposite($this->lang['strtypeneedsname']);
498
499
                    return;
500
                }
501
502
                if ('' === $fields || !\is_numeric($fields) || (int) $fields !== $fields || 0 >= $fields) {
503
                    $_REQUEST['stage'] = 1;
504
                    $this->doCreateComposite($this->lang['strtypeneedscols']);
505
506
                    return;
507
                }
508
509
                $status = $data->createCompositeType(
510
                    $_REQUEST['name'],
511
                    $_REQUEST['fields'],
512
                    $_REQUEST['field'],
513
                    $_REQUEST['type'],
514
                    $_REQUEST['array'],
515
                    $_REQUEST['length'],
516
                    $_REQUEST['colcomment'],
517
                    $_REQUEST['typcomment']
518
                );
519
520
                if (0 === $status) {
521
                    $this->doDefault($this->lang['strtypecreated']);
522
                } elseif (-1 === $status) {
523
                    $_REQUEST['stage'] = 2;
524
                    $this->doCreateComposite($this->lang['strtypeneedsfield']);
525
526
                    return;
527
                } else {
528
                    $_REQUEST['stage'] = 2;
529
                    $this->doCreateComposite($this->lang['strtypecreatedbad']);
530
531
                    return;
532
                }
533
534
                break;
535
536
            default:
537
                echo "<p>{$this->lang['strinvalidparam']}</p>" . \PHP_EOL;
538
        }
539
    }
540
541
    /**
542
     * Displays a screen where they can enter a new enum type.
543
     *
544
     * @param mixed $msg
545
     */
546
    public function doCreateEnum($msg = ''): void
547
    {
548
        $data = $this->misc->getDatabaseAccessor();
549
550
        $this->coalesceArr($_REQUEST, 'stage', 1);
551
552
        $this->coalesceArr($_REQUEST, 'name', '');
553
554
        $this->coalesceArr($_REQUEST, 'values', '');
555
556
        $this->coalesceArr($_REQUEST, 'typcomment', '');
557
558
        switch ($_REQUEST['stage']) {
559
            case 1:
560
                $this->printTrail('type');
561
                $this->printTitle($this->lang['strcreateenumtype'], 'pg.type.create');
562
                $this->printMsg($msg);
563
564
                echo '<form action="' . \containerInstance()->subFolder . '/src/views/types" method="post">' . \PHP_EOL;
565
                echo '<table>' . \PHP_EOL;
566
                echo "\t<tr>\n\t\t<th class=\"data left required\">{$this->lang['strname']}</th>" . \PHP_EOL;
567
                echo "\t\t<td class=\"data\"><input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"",
568
                \htmlspecialchars($_REQUEST['name']), "\" /></td>\n\t</tr>" . \PHP_EOL;
569
                echo "\t<tr>\n\t\t<th class=\"data left required\">{$this->lang['strnumvalues']}</th>" . \PHP_EOL;
570
                echo "\t\t<td class=\"data\"><input name=\"values\" size=\"5\" maxlength=\"{$data->_maxNameLen}\" value=\"",
571
                \htmlspecialchars($_REQUEST['values']), "\" /></td>\n\t</tr>" . \PHP_EOL;
572
573
                echo "\t<tr>\n\t\t<th class=\"data left\">{$this->lang['strcomment']}</th>" . \PHP_EOL;
574
                echo "\t\t<td><textarea name=\"typcomment\" rows=\"3\" cols=\"32\">",
575
                \htmlspecialchars($_REQUEST['typcomment']), "</textarea></td>\n\t</tr>" . \PHP_EOL;
576
577
                echo '</table>' . \PHP_EOL;
578
                echo '<p><input type="hidden" name="action" value="create_enum" />' . \PHP_EOL;
579
                echo '<input type="hidden" name="stage" value="2" />' . \PHP_EOL;
580
                echo $this->view->form;
581
                echo "<input type=\"submit\" value=\"{$this->lang['strnext']}\" />" . \PHP_EOL;
582
                echo \sprintf('<input type="submit" name="cancel" value="%s"  /></p>%s', $this->lang['strcancel'], \PHP_EOL);
583
                echo '</form>' . \PHP_EOL;
584
585
                break;
586
            case 2:
587
                // Check inputs
588
                $values = \trim($_REQUEST['values']);
589
590
                if ('' === \trim($_REQUEST['name'])) {
591
                    $_REQUEST['stage'] = 1;
592
                    $this->doCreateEnum($this->lang['strtypeneedsname']);
593
594
                    return;
595
                }
596
597
                if ('' === $values || !\is_numeric($values) || (int) $values !== $values || 1 > $values) {
598
                    $_REQUEST['stage'] = 1;
599
                    $this->doCreateEnum($this->lang['strtypeneedsvals']);
600
601
                    return;
602
                }
603
604
                $this->printTrail('schema');
605
                $this->printTitle($this->lang['strcreateenumtype'], 'pg.type.create');
606
                $this->printMsg($msg);
607
608
                echo '<form action="' . \containerInstance()->subFolder . '/src/views/types" method="post">' . \PHP_EOL;
609
610
                // Output table header
611
                echo '<table>' . \PHP_EOL;
612
                echo "\t<tr><th colspan=\"2\" class=\"data required\">{$this->lang['strvalue']}</th></tr>" . \PHP_EOL;
613
614
                for ($i = 0; $i < $_REQUEST['values']; ++$i) {
615
                    if (!isset($_REQUEST['value'][$i])) {
616
                        $_REQUEST['value'][$i] = '';
617
                    }
618
619
                    echo "\t<tr>\n\t\t<td>", $i + 1, '.&nbsp;</td>' . \PHP_EOL;
620
                    echo "\t\t<td><input name=\"value[{$i}]\" size=\"16\" maxlength=\"{$data->_maxNameLen}\" value=\"",
621
                    \htmlspecialchars($_REQUEST['value'][$i]), "\" /></td>\n\t</tr>" . \PHP_EOL;
622
                }
623
                echo '</table>' . \PHP_EOL;
624
                echo '<p><input type="hidden" name="action" value="create_enum" />' . \PHP_EOL;
625
                echo '<input type="hidden" name="stage" value="3" />' . \PHP_EOL;
626
                echo $this->view->form;
627
                echo '<input type="hidden" name="name" value="', \htmlspecialchars($_REQUEST['name']), '" />' . \PHP_EOL;
628
                echo '<input type="hidden" name="values" value="', \htmlspecialchars($_REQUEST['values']), '" />' . \PHP_EOL;
629
                echo '<input type="hidden" name="typcomment" value="', \htmlspecialchars($_REQUEST['typcomment']), '" />' . \PHP_EOL;
630
                echo "<input type=\"submit\" value=\"{$this->lang['strcreate']}\" />" . \PHP_EOL;
631
                echo \sprintf('<input type="submit" name="cancel" value="%s"  /></p>%s', $this->lang['strcancel'], \PHP_EOL);
632
                echo '</form>' . \PHP_EOL;
633
634
                break;
635
            case 3:
636
                // Check inputs
637
                $values = \trim($_REQUEST['values']);
638
639
                if ('' === \trim($_REQUEST['name'])) {
640
                    $_REQUEST['stage'] = 1;
641
                    $this->doCreateEnum($this->lang['strtypeneedsname']);
642
643
                    return;
644
                }
645
646
                if ('' === $values || !\is_numeric($values) || (int) $values !== $values || 0 >= $values) {
647
                    $_REQUEST['stage'] = 1;
648
                    $this->doCreateEnum($this->lang['strtypeneedsvals']);
649
650
                    return;
651
                }
652
653
                $status = $data->createEnumType($_REQUEST['name'], $_REQUEST['value'], $_REQUEST['typcomment']);
654
655
                if (0 === $status) {
656
                    $this->doDefault($this->lang['strtypecreated']);
657
                } elseif (-1 === $status) {
658
                    $_REQUEST['stage'] = 2;
659
                    $this->doCreateEnum($this->lang['strtypeneedsvalue']);
660
661
                    return;
662
                } else {
663
                    $_REQUEST['stage'] = 2;
664
                    $this->doCreateEnum($this->lang['strtypecreatedbad']);
665
666
                    return;
667
                }
668
669
                break;
670
671
            default:
672
                echo "<p>{$this->lang['strinvalidparam']}</p>" . \PHP_EOL;
673
        }
674
    }
675
676
    /**
677
     * Displays a screen where they can enter a new type.
678
     *
679
     * @param mixed $msg
680
     */
681
    public function doCreate($msg = ''): void
682
    {
683
        $data = $this->misc->getDatabaseAccessor();
684
685
        $this->coalesceArr($_POST, 'typname', '');
686
687
        $this->coalesceArr($_POST, 'typin', '');
688
689
        $this->coalesceArr($_POST, 'typout', '');
690
691
        $this->coalesceArr($_POST, 'typlen', '');
692
693
        $this->coalesceArr($_POST, 'typdef', '');
694
695
        $this->coalesceArr($_POST, 'typelem', '');
696
697
        $this->coalesceArr($_POST, 'typdelim', '');
698
699
        $this->coalesceArr($_POST, 'typalign', $data->typAlignDef);
700
701
        $this->coalesceArr($_POST, 'typstorage', $data->typStorageDef);
702
703
        // Retrieve all functions and types in the database
704
        $funcs = $data->getFunctions(true);
705
        $types = $data->getTypes(true);
706
707
        $this->printTrail('schema');
708
        $this->printTitle($this->lang['strcreatetype'], 'pg.type.create');
709
        $this->printMsg($msg);
710
711
        echo '<form action="' . \containerInstance()->subFolder . '/src/views/types" method="post">' . \PHP_EOL;
712
        echo '<table>' . \PHP_EOL;
713
        echo "<tr><th class=\"data left required\">{$this->lang['strname']}</th>" . \PHP_EOL;
714
        echo "<td class=\"data1\"><input name=\"typname\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"",
715
        \htmlspecialchars($_POST['typname']), '" /></td></tr>' . \PHP_EOL;
716
        echo "<tr><th class=\"data left required\">{$this->lang['strinputfn']}</th>" . \PHP_EOL;
717
        echo '<td class="data1"><select name="typin">';
718
719
        while (!$funcs->EOF) {
720
            $proname = \htmlspecialchars($funcs->fields['proname']);
721
            echo "<option value=\"{$proname}\"",
722
            ($proname === $_POST['typin']) ? ' selected="selected"' : '', ">{$proname}</option>" . \PHP_EOL;
723
            $funcs->moveNext();
724
        }
725
        echo '</select></td></tr>' . \PHP_EOL;
726
        echo "<tr><th class=\"data left required\">{$this->lang['stroutputfn']}</th>" . \PHP_EOL;
727
        echo '<td class="data1"><select name="typout">';
728
        $funcs->moveFirst();
729
730
        while (!$funcs->EOF) {
731
            $proname = \htmlspecialchars($funcs->fields['proname']);
732
            echo "<option value=\"{$proname}\"",
733
            ($proname === $_POST['typout']) ? ' selected="selected"' : '', ">{$proname}</option>" . \PHP_EOL;
734
            $funcs->moveNext();
735
        }
736
        echo '</select></td></tr>' . \PHP_EOL;
737
        echo '<tr><th class="data left' . (\version_compare($data->major_version, '7.4', '<') ? ' required' : '') . "\">{$this->lang['strlength']}</th>" . \PHP_EOL;
738
        echo '<td class="data1"><input name="typlen" size="8" value="',
739
        \htmlspecialchars($_POST['typlen']), '" /></td></tr>';
740
        echo "<tr><th class=\"data left\">{$this->lang['strdefault']}</th>" . \PHP_EOL;
741
        echo '<td class="data1"><input name="typdef" size="8" value="',
742
        \htmlspecialchars($_POST['typdef']), '" /></td></tr>';
743
        echo "<tr><th class=\"data left\">{$this->lang['strelement']}</th>" . \PHP_EOL;
744
        echo '<td class="data1"><select name="typelem">';
745
        echo '<option value=""></option>' . \PHP_EOL;
746
747
        while (!$types->EOF) {
748
            $currname = \htmlspecialchars($types->fields['typname']);
749
            echo "<option value=\"{$currname}\"",
750
            ($currname === $_POST['typelem']) ? ' selected="selected"' : '', ">{$currname}</option>" . \PHP_EOL;
751
            $types->moveNext();
752
        }
753
        echo '</select></td></tr>' . \PHP_EOL;
754
        echo "<tr><th class=\"data left\">{$this->lang['strdelimiter']}</th>" . \PHP_EOL;
755
        echo '<td class="data1"><input name="typdelim" size="1" maxlength="1" value="',
756
        \htmlspecialchars($_POST['typdelim']), '" /></td></tr>';
757
        echo "<tr><th class=\"data left\"><label for=\"typbyval\">{$this->lang['strpassbyval']}</label></th>" . \PHP_EOL;
758
        echo '<td class="data1"><input type="checkbox" id="typbyval" name="typbyval"',
759
        isset($_POST['typbyval']) ? ' checked="checked"' : '', ' /></td></tr>';
760
        echo "<tr><th class=\"data left\">{$this->lang['stralignment']}</th>" . \PHP_EOL;
761
        echo '<td class="data1"><select name="typalign">';
762
763
        foreach ($data->typAligns as $v) {
764
            echo "<option value=\"{$v}\"",
765
            ($v === $_POST['typalign']) ? ' selected="selected"' : '', ">{$v}</option>" . \PHP_EOL;
766
        }
767
        echo '</select></td></tr>' . \PHP_EOL;
768
        echo "<tr><th class=\"data left\">{$this->lang['strstorage']}</th>" . \PHP_EOL;
769
        echo '<td class="data1"><select name="typstorage">';
770
771
        foreach ($data->typStorages as $v) {
772
            echo "<option value=\"{$v}\"",
773
            ($v === $_POST['typstorage']) ? ' selected="selected"' : '', ">{$v}</option>" . \PHP_EOL;
774
        }
775
        echo '</select></td></tr>' . \PHP_EOL;
776
        echo '</table>' . \PHP_EOL;
777
        echo '<p><input type="hidden" name="action" value="save_create" />' . \PHP_EOL;
778
        echo $this->view->form;
779
        echo "<input type=\"submit\" value=\"{$this->lang['strcreate']}\" />" . \PHP_EOL;
780
        echo \sprintf('<input type="submit" name="cancel" value="%s"  /></p>%s', $this->lang['strcancel'], \PHP_EOL);
781
        echo '</form>' . \PHP_EOL;
782
    }
783
784
    /**
785
     * Actually creates the new type in the database.
786
     */
787
    public function doSaveCreate(): void
788
    {
789
        $data = $this->misc->getDatabaseAccessor();
790
791
        // Check that they've given a name and a length.
792
        // Note: We're assuming they've given in and out functions here
793
        // which might be unwise...
794
        if ('' === $_POST['typname']) {
795
            $this->doCreate($this->lang['strtypeneedsname']);
796
        } elseif ('' === $_POST['typlen']) {
797
            $this->doCreate($this->lang['strtypeneedslen']);
798
        } else {
799
            $status = $data->createType(
800
                $_POST['typname'],
801
                $_POST['typin'],
802
                $_POST['typout'],
803
                $_POST['typlen'],
804
                $_POST['typdef'],
805
                $_POST['typelem'],
806
                $_POST['typdelim'],
807
                isset($_POST['typbyval']),
808
                $_POST['typalign'],
809
                $_POST['typstorage']
810
            );
811
812
            if (0 === $status) {
813
                $this->doDefault($this->lang['strtypecreated']);
814
            } else {
815
                $this->doCreate($this->lang['strtypecreatedbad']);
816
            }
817
        }
818
    }
819
}
820