Passed
Push — develop ( c2019a...2cab77 )
by Felipe
04:50
created

TypesController   F

Complexity

Total Complexity 90

Size/Duplication

Total Lines 786
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 90
dl 0
loc 786
rs 1.263
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
C render() 0 61 13
B doDefault() 0 116 3
C doProperties() 0 85 8
A doTree() 0 23 1
B doDrop() 0 24 3
D doCreate() 0 96 13
D doCreateComposite() 0 165 27
D doCreateEnum() 0 124 18
B doSaveCreate() 0 28 4

How to fix   Complexity   

Complex Class

Complex classes like TypesController 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 TypesController, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * PHPPgAdmin v6.0.0-beta.48
5
 */
6
7
namespace PHPPgAdmin\Controller;
8
9
use PHPPgAdmin\Decorators\Decorator;
10
11
/**
12
 * Base controller class.
13
 *
14
 * @package PHPPgAdmin
15
 */
16
class TypesController extends BaseController
17
{
18
    public $controller_title = 'strtypes';
19
20
    /**
21
     * Default method to render the controller according to the action parameter.
22
     */
23
    public function render()
24
    {
25
        if ('tree' == $this->action) {
26
            return $this->doTree();
27
        }
28
29
        $this->printHeader();
30
        $this->printBody();
31
32
        switch ($this->action) {
33
            case 'create_comp':
34
                if (isset($_POST['cancel'])) {
35
                    $this->doDefault();
36
                } else {
37
                    $this->doCreateComposite();
38
                }
39
40
                break;
41
            case 'create_enum':
42
                if (isset($_POST['cancel'])) {
43
                    $this->doDefault();
44
                } else {
45
                    $this->doCreateEnum();
46
                }
47
48
                break;
49
            case 'save_create':
50
                if (isset($_POST['cancel'])) {
51
                    $this->doDefault();
52
                } else {
53
                    $this->doSaveCreate();
54
                }
55
56
                break;
57
            case 'create':
58
                $this->doCreate();
59
60
                break;
61
            case 'drop':
62
                if (isset($_POST['cancel'])) {
63
                    $this->doDefault();
64
                } else {
65
                    $this->doDrop(false);
66
                }
67
68
                break;
69
            case 'confirm_drop':
70
                $this->doDrop(true);
71
72
                break;
73
            case 'properties':
74
                $this->doProperties();
75
76
                break;
77
            default:
78
                $this->doDefault();
79
80
                break;
81
        }
82
83
        return $this->printFooter();
84
    }
85
86
    /**
87
     * Show default list of types in the database.
88
     *
89
     * @param mixed $msg
90
     */
91
    public function doDefault($msg = '')
92
    {
93
        $data = $this->misc->getDatabaseAccessor();
94
95
        $this->printTrail('schema');
96
        $this->printTabs('schema', 'types');
97
        $this->printMsg($msg);
98
99
        $types = $data->getTypes();
100
101
        $columns = [
102
            'type'    => [
103
                'title' => $this->lang['strtype'],
104
                'field' => Decorator::field('typname'),
105
                'url'   => "types?action=properties&amp;{$this->misc->href}&amp;",
106
                'vars'  => ['type' => 'basename'],
107
            ],
108
            'owner'   => [
109
                'title' => $this->lang['strowner'],
110
                'field' => Decorator::field('typowner'),
111
            ],
112
            'flavour' => [
113
                'title'  => $this->lang['strflavor'],
114
                'field'  => Decorator::field('typtype'),
115
                'type'   => 'verbatim',
116
                'params' => [
117
                    'map'   => [
118
                        'b' => $this->lang['strbasetype'],
119
                        'c' => $this->lang['strcompositetype'],
120
                        'd' => $this->lang['strdomain'],
121
                        'p' => $this->lang['strpseudotype'],
122
                        'e' => $this->lang['strenum'],
123
                    ],
124
                    'align' => 'center',
125
                ],
126
            ],
127
            'actions' => [
128
                'title' => $this->lang['stractions'],
129
            ],
130
            'comment' => [
131
                'title' => $this->lang['strcomment'],
132
                'field' => Decorator::field('typcomment'),
133
            ],
134
        ];
135
136
        if (!isset($types->fields['typtype'])) {
137
            unset($columns['flavour']);
138
        }
139
140
        $actions = [
141
            'drop' => [
142
                'content' => $this->lang['strdrop'],
143
                'attr'    => [
144
                    'href' => [
145
                        'url'     => 'types',
146
                        'urlvars' => [
147
                            'action' => 'confirm_drop',
148
                            'type'   => Decorator::field('basename'),
149
                        ],
150
                    ],
151
                ],
152
            ],
153
        ];
154
155
        echo $this->printTable($types, $columns, $actions, 'types-types', $this->lang['strnotypes']);
156
157
        $navlinks = [
158
            'create'     => [
159
                'attr'    => [
160
                    'href' => [
161
                        'url'     => 'types',
162
                        'urlvars' => [
163
                            'action'   => 'create',
164
                            'server'   => $_REQUEST['server'],
165
                            'database' => $_REQUEST['database'],
166
                            'schema'   => $_REQUEST['schema'],
167
                        ],
168
                    ],
169
                ],
170
                'content' => $this->lang['strcreatetype'],
171
            ],
172
            'createcomp' => [
173
                'attr'    => [
174
                    'href' => [
175
                        'url'     => 'types',
176
                        'urlvars' => [
177
                            'action'   => 'create_comp',
178
                            'server'   => $_REQUEST['server'],
179
                            'database' => $_REQUEST['database'],
180
                            'schema'   => $_REQUEST['schema'],
181
                        ],
182
                    ],
183
                ],
184
                'content' => $this->lang['strcreatecomptype'],
185
            ],
186
            'createenum' => [
187
                'attr'    => [
188
                    'href' => [
189
                        'url'     => 'types',
190
                        'urlvars' => [
191
                            'action'   => 'create_enum',
192
                            'server'   => $_REQUEST['server'],
193
                            'database' => $_REQUEST['database'],
194
                            'schema'   => $_REQUEST['schema'],
195
                        ],
196
                    ],
197
                ],
198
                'content' => $this->lang['strcreateenumtype'],
199
            ],
200
        ];
201
202
        if (!$data->hasEnumTypes()) {
203
            unset($navlinks['enum']);
204
        }
205
206
        $this->printNavLinks($navlinks, 'types-types', get_defined_vars());
207
    }
208
209
    /**
210
     * Generate XML for the browser tree.
211
     */
212
    public function doTree()
213
    {
214
        $data = $this->misc->getDatabaseAccessor();
215
216
        $types = $data->getTypes();
217
218
        $reqvars = $this->misc->getRequestVars('type');
219
220
        $attrs = [
221
            'text'    => Decorator::field('typname'),
222
            'icon'    => 'Type',
223
            'toolTip' => Decorator::field('typcomment'),
224
            'action'  => Decorator::actionurl(
225
                'types',
226
                $reqvars,
227
                [
228
                    'action' => 'properties',
229
                    'type'   => Decorator::field('basename'),
230
                ]
231
            ),
232
        ];
233
234
        return $this->printTree($types, $attrs, 'types');
235
    }
236
237
    /**
238
     * Show read only properties for a type.
239
     *
240
     * @param mixed $msg
241
     */
242
    public function doProperties($msg = '')
243
    {
244
        $data = $this->misc->getDatabaseAccessor();
245
        // Get type (using base name)
246
        $typedata = $data->getType($_REQUEST['type']);
247
248
        $this->printTrail('type');
249
        $this->printTitle($this->lang['strproperties'], 'pg.type');
250
        $this->printMsg($msg);
251
252
        $attPre = function (&$rowdata) use ($data) {
253
            $rowdata->fields['+type'] = $data->formatType($rowdata->fields['type'], $rowdata->fields['atttypmod']);
254
        };
255
256
        if ($typedata->recordCount() > 0) {
257
            $vals = false;
258
            switch ($typedata->fields['typtype']) {
259
                case 'c':
260
                    $attrs = $data->getTableAttributes($_REQUEST['type']);
261
262
                    $columns = [
263
                        'field'   => [
264
                            'title' => $this->lang['strfield'],
265
                            'field' => Decorator::field('attname'),
266
                        ],
267
                        'type'    => [
268
                            'title' => $this->lang['strtype'],
269
                            'field' => Decorator::field('+type'),
270
                        ],
271
                        'comment' => [
272
                            'title' => $this->lang['strcomment'],
273
                            'field' => Decorator::field('comment'),
274
                        ],
275
                    ];
276
277
                    $actions = [];
278
279
                    echo $this->printTable($attrs, $columns, $actions, 'types-properties', $this->lang['strnodata'], $attPre);
280
281
                    break;
282
                case 'e':
283
                    $vals = $data->getEnumValues($typedata->fields['typname']);
284
                // no break
285
                default:
286
                    $byval = $data->phpBool($typedata->fields['typbyval']);
287
                    echo '<table>'.PHP_EOL;
288
                    echo "<tr><th class=\"data left\">{$this->lang['strname']}</th>".PHP_EOL;
289
                    echo '<td class="data1">', $this->misc->printVal($typedata->fields['typname']), '</td></tr>'.PHP_EOL;
290
                    echo "<tr><th class=\"data left\">{$this->lang['strinputfn']}</th>".PHP_EOL;
291
                    echo '<td class="data1">', $this->misc->printVal($typedata->fields['typin']), '</td></tr>'.PHP_EOL;
292
                    echo "<tr><th class=\"data left\">{$this->lang['stroutputfn']}</th>".PHP_EOL;
293
                    echo '<td class="data1">', $this->misc->printVal($typedata->fields['typout']), '</td></tr>'.PHP_EOL;
294
                    echo "<tr><th class=\"data left\">{$this->lang['strlength']}</th>".PHP_EOL;
295
                    echo '<td class="data1">', $this->misc->printVal($typedata->fields['typlen']), '</td></tr>'.PHP_EOL;
296
                    echo "<tr><th class=\"data left\">{$this->lang['strpassbyval']}</th>".PHP_EOL;
297
                    echo '<td class="data1">', ($byval) ? $this->lang['stryes'] : $this->lang['strno'], '</td></tr>'.PHP_EOL;
298
                    echo "<tr><th class=\"data left\">{$this->lang['stralignment']}</th>".PHP_EOL;
299
                    echo '<td class="data1">', $this->misc->printVal($typedata->fields['typalign']), '</td></tr>'.PHP_EOL;
300
                    if ($data->hasEnumTypes() && $vals) {
301
                        $vals   = $vals->getArray();
302
                        $nbVals = count($vals);
303
                        echo "<tr>\n\t<th class=\"data left\" rowspan=\"${nbVals}\">{$this->lang['strenumvalues']}</th>".PHP_EOL;
304
                        echo "<td class=\"data2\">{$vals[0]['enumval']}</td></tr>".PHP_EOL;
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)
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="'.\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->misc->form;
350
            echo "<input type=\"submit\" name=\"drop\" value=\"{$this->lang['strdrop']}\" />".PHP_EOL;
351
            echo "<input type=\"submit\" name=\"cancel\" value=\"{$this->lang['strcancel']}\" /></p>".PHP_EOL;
352
            echo '</form>'.PHP_EOL;
353
        } else {
354
            $status = $data->dropType($_POST['type'], isset($_POST['cascade']));
355
            if (0 == $status) {
356
                $this->doDefault($this->lang['strtypedropped']);
357
            } else {
358
                $this->doDefault($this->lang['strtypedroppedbad']);
359
            }
360
        }
361
    }
362
363
    /**
364
     * Displays a screen where they can enter a new composite type.
365
     *
366
     * @param mixed $msg
367
     */
368
    public function doCreateComposite($msg = '')
369
    {
370
        $data = $this->misc->getDatabaseAccessor();
371
372
        $this->coalesceArr($_REQUEST, 'stage', 1);
373
374
        $this->coalesceArr($_REQUEST, 'name', '');
375
376
        $this->coalesceArr($_REQUEST, 'fields', '');
377
378
        $this->coalesceArr($_REQUEST, 'typcomment', '');
379
380
        switch ($_REQUEST['stage']) {
381
            case 1:
382
                $this->printTrail('type');
383
                $this->printTitle($this->lang['strcreatecomptype'], 'pg.type.create');
384
                $this->printMsg($msg);
385
386
                echo '<form action="'.\SUBFOLDER.'/src/views/types" method="post">'.PHP_EOL;
387
                echo '<table>'.PHP_EOL;
388
                echo "\t<tr>\n\t\t<th class=\"data left required\">{$this->lang['strname']}</th>".PHP_EOL;
389
                echo "\t\t<td class=\"data\"><input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"",
390
                htmlspecialchars($_REQUEST['name']), "\" /></td>\n\t</tr>".PHP_EOL;
391
                echo "\t<tr>\n\t\t<th class=\"data left required\">{$this->lang['strnumfields']}</th>".PHP_EOL;
392
                echo "\t\t<td class=\"data\"><input name=\"fields\" size=\"5\" maxlength=\"{$data->_maxNameLen}\" value=\"",
393
                htmlspecialchars($_REQUEST['fields']), "\" /></td>\n\t</tr>".PHP_EOL;
394
395
                echo "\t<tr>\n\t\t<th class=\"data left\">{$this->lang['strcomment']}</th>".PHP_EOL;
396
                echo "\t\t<td><textarea name=\"typcomment\" rows=\"3\" cols=\"32\">",
397
                htmlspecialchars($_REQUEST['typcomment']), "</textarea></td>\n\t</tr>".PHP_EOL;
398
399
                echo '</table>'.PHP_EOL;
400
                echo '<p><input type="hidden" name="action" value="create_comp" />'.PHP_EOL;
401
                echo '<input type="hidden" name="stage" value="2" />'.PHP_EOL;
402
                echo $this->misc->form;
403
                echo "<input type=\"submit\" value=\"{$this->lang['strnext']}\" />".PHP_EOL;
404
                echo "<input type=\"submit\" name=\"cancel\" value=\"{$this->lang['strcancel']}\" /></p>".PHP_EOL;
405
                echo '</form>'.PHP_EOL;
406
407
                break;
408
            case 2:
409
410
                // Check inputs
411
                $fields = trim($_REQUEST['fields']);
412
                if ('' == trim($_REQUEST['name'])) {
413
                    $_REQUEST['stage'] = 1;
414
                    $this->doCreateComposite($this->lang['strtypeneedsname']);
415
416
                    return;
417
                }
418
                if ('' == $fields || !is_numeric($fields) || $fields != (int) $fields || $fields < 1) {
419
                    $_REQUEST['stage'] = 1;
420
                    $this->doCreateComposite($this->lang['strtypeneedscols']);
421
422
                    return;
423
                }
424
425
                $types = $data->getTypes(true, false, true);
426
427
                $this->printTrail('schema');
428
                $this->printTitle($this->lang['strcreatecomptype'], 'pg.type.create');
429
                $this->printMsg($msg);
430
431
                echo '<form action="'.\SUBFOLDER.'/src/views/types" method="post">'.PHP_EOL;
432
433
                // Output table header
434
                echo '<table>'.PHP_EOL;
435
                echo "\t<tr><th colspan=\"2\" class=\"data required\">{$this->lang['strfield']}</th><th colspan=\"2\" class=\"data required\">{$this->lang['strtype']}</th>";
436
                echo "<th class=\"data\">{$this->lang['strlength']}</th><th class=\"data\">{$this->lang['strcomment']}</th></tr>".PHP_EOL;
437
438
                for ($i = 0; $i < $_REQUEST['fields']; ++$i) {
439
                    if (!isset($_REQUEST['field'][$i])) {
440
                        $_REQUEST['field'][$i] = '';
441
                    }
442
443
                    if (!isset($_REQUEST['length'][$i])) {
444
                        $_REQUEST['length'][$i] = '';
445
                    }
446
447
                    if (!isset($_REQUEST['colcomment'][$i])) {
448
                        $_REQUEST['colcomment'][$i] = '';
449
                    }
450
451
                    echo "\t<tr>\n\t\t<td>", $i + 1, '.&nbsp;</td>'.PHP_EOL;
452
                    echo "\t\t<td><input name=\"field[{$i}]\" size=\"16\" maxlength=\"{$data->_maxNameLen}\" value=\"",
453
                    htmlspecialchars($_REQUEST['field'][$i]), '" /></td>'.PHP_EOL;
454
                    echo "\t\t<td>\n\t\t\t<select name=\"type[{$i}]\">".PHP_EOL;
455
                    $types->moveFirst();
456
                    while (!$types->EOF) {
457
                        $typname = $types->fields['typname'];
458
                        echo "\t\t\t\t<option value=\"", htmlspecialchars($typname), '"',
459
                        (isset($_REQUEST['type'][$i]) && $_REQUEST['type'][$i] == $typname) ? ' selected="selected"' : '', '>',
460
                        $this->misc->printVal($typname), '</option>'.PHP_EOL;
461
                        $types->moveNext();
462
                    }
463
                    echo "\t\t\t</select>\n\t\t</td>".PHP_EOL;
464
465
                    // Output array type selector
466
                    echo "\t\t<td>\n\t\t\t<select name=\"array[{$i}]\">".PHP_EOL;
467
                    echo "\t\t\t\t<option value=\"\"", (isset($_REQUEST['array'][$i]) && $_REQUEST['array'][$i] == '') ? ' selected="selected"' : '', '></option>'.PHP_EOL;
468
                    echo "\t\t\t\t<option value=\"[]\"", (isset($_REQUEST['array'][$i]) && $_REQUEST['array'][$i] == '[]') ? ' selected="selected"' : '', '>[ ]</option>'.PHP_EOL;
469
                    echo "\t\t\t</select>\n\t\t</td>".PHP_EOL;
470
471
                    echo "\t\t<td><input name=\"length[{$i}]\" size=\"10\" value=\"",
472
                    htmlspecialchars($_REQUEST['length'][$i]), '" /></td>'.PHP_EOL;
473
                    echo "\t\t<td><input name=\"colcomment[{$i}]\" size=\"40\" value=\"",
474
                    htmlspecialchars($_REQUEST['colcomment'][$i]), "\" /></td>\n\t</tr>".PHP_EOL;
475
                }
476
                echo '</table>'.PHP_EOL;
477
                echo '<p><input type="hidden" name="action" value="create_comp" />'.PHP_EOL;
478
                echo '<input type="hidden" name="stage" value="3" />'.PHP_EOL;
479
                echo $this->misc->form;
480
                echo '<input type="hidden" name="name" value="', htmlspecialchars($_REQUEST['name']), '" />'.PHP_EOL;
481
                echo '<input type="hidden" name="fields" value="', htmlspecialchars($_REQUEST['fields']), '" />'.PHP_EOL;
482
                echo '<input type="hidden" name="typcomment" value="', htmlspecialchars($_REQUEST['typcomment']), '" />'.PHP_EOL;
483
                echo "<input type=\"submit\" value=\"{$this->lang['strcreate']}\" />".PHP_EOL;
484
                echo "<input type=\"submit\" name=\"cancel\" value=\"{$this->lang['strcancel']}\" /></p>".PHP_EOL;
485
                echo '</form>'.PHP_EOL;
486
487
                break;
488
            case 3:
489
490
                // Check inputs
491
                $fields = trim($_REQUEST['fields']);
492
                if ('' == trim($_REQUEST['name'])) {
493
                    $_REQUEST['stage'] = 1;
494
                    $this->doCreateComposite($this->lang['strtypeneedsname']);
495
496
                    return;
497
                }
498
                if ('' == $fields || !is_numeric($fields) || $fields != (int) $fields || $fields <= 0) {
499
                    $_REQUEST['stage'] = 1;
500
                    $this->doCreateComposite($this->lang['strtypeneedscols']);
501
502
                    return;
503
                }
504
505
                $status = $data->createCompositeType(
506
                    $_REQUEST['name'],
507
                    $_REQUEST['fields'],
508
                    $_REQUEST['field'],
509
                    $_REQUEST['type'],
510
                    $_REQUEST['array'],
511
                    $_REQUEST['length'],
512
                    $_REQUEST['colcomment'],
513
                    $_REQUEST['typcomment']
514
                );
515
516
                if (0 == $status) {
517
                    $this->doDefault($this->lang['strtypecreated']);
518
                } elseif ($status == -1) {
519
                    $_REQUEST['stage'] = 2;
520
                    $this->doCreateComposite($this->lang['strtypeneedsfield']);
521
522
                    return;
523
                } else {
524
                    $_REQUEST['stage'] = 2;
525
                    $this->doCreateComposite($this->lang['strtypecreatedbad']);
526
527
                    return;
528
                }
529
530
                break;
531
            default:
532
                echo "<p>{$this->lang['strinvalidparam']}</p>".PHP_EOL;
533
        }
534
    }
535
536
    /**
537
     * Displays a screen where they can enter a new enum type.
538
     *
539
     * @param mixed $msg
540
     */
541
    public function doCreateEnum($msg = '')
542
    {
543
        $data = $this->misc->getDatabaseAccessor();
544
545
        $this->coalesceArr($_REQUEST, 'stage', 1);
546
547
        $this->coalesceArr($_REQUEST, 'name', '');
548
549
        $this->coalesceArr($_REQUEST, 'values', '');
550
551
        $this->coalesceArr($_REQUEST, 'typcomment', '');
552
553
        switch ($_REQUEST['stage']) {
554
            case 1:
555
                $this->printTrail('type');
556
                $this->printTitle($this->lang['strcreateenumtype'], 'pg.type.create');
557
                $this->printMsg($msg);
558
559
                echo '<form action="'.\SUBFOLDER.'/src/views/types" method="post">'.PHP_EOL;
560
                echo '<table>'.PHP_EOL;
561
                echo "\t<tr>\n\t\t<th class=\"data left required\">{$this->lang['strname']}</th>".PHP_EOL;
562
                echo "\t\t<td class=\"data\"><input name=\"name\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"",
563
                htmlspecialchars($_REQUEST['name']), "\" /></td>\n\t</tr>".PHP_EOL;
564
                echo "\t<tr>\n\t\t<th class=\"data left required\">{$this->lang['strnumvalues']}</th>".PHP_EOL;
565
                echo "\t\t<td class=\"data\"><input name=\"values\" size=\"5\" maxlength=\"{$data->_maxNameLen}\" value=\"",
566
                htmlspecialchars($_REQUEST['values']), "\" /></td>\n\t</tr>".PHP_EOL;
567
568
                echo "\t<tr>\n\t\t<th class=\"data left\">{$this->lang['strcomment']}</th>".PHP_EOL;
569
                echo "\t\t<td><textarea name=\"typcomment\" rows=\"3\" cols=\"32\">",
570
                htmlspecialchars($_REQUEST['typcomment']), "</textarea></td>\n\t</tr>".PHP_EOL;
571
572
                echo '</table>'.PHP_EOL;
573
                echo '<p><input type="hidden" name="action" value="create_enum" />'.PHP_EOL;
574
                echo '<input type="hidden" name="stage" value="2" />'.PHP_EOL;
575
                echo $this->misc->form;
576
                echo "<input type=\"submit\" value=\"{$this->lang['strnext']}\" />".PHP_EOL;
577
                echo "<input type=\"submit\" name=\"cancel\" value=\"{$this->lang['strcancel']}\" /></p>".PHP_EOL;
578
                echo '</form>'.PHP_EOL;
579
580
                break;
581
            case 2:
582
583
                // Check inputs
584
                $values = trim($_REQUEST['values']);
585
                if ('' == trim($_REQUEST['name'])) {
586
                    $_REQUEST['stage'] = 1;
587
                    $this->doCreateEnum($this->lang['strtypeneedsname']);
588
589
                    return;
590
                }
591
                if ('' == $values || !is_numeric($values) || $values != (int) $values || $values < 1) {
592
                    $_REQUEST['stage'] = 1;
593
                    $this->doCreateEnum($this->lang['strtypeneedsvals']);
594
595
                    return;
596
                }
597
598
                $this->printTrail('schema');
599
                $this->printTitle($this->lang['strcreateenumtype'], 'pg.type.create');
600
                $this->printMsg($msg);
601
602
                echo '<form action="'.\SUBFOLDER.'/src/views/types" method="post">'.PHP_EOL;
603
604
                // Output table header
605
                echo '<table>'.PHP_EOL;
606
                echo "\t<tr><th colspan=\"2\" class=\"data required\">{$this->lang['strvalue']}</th></tr>".PHP_EOL;
607
608
                for ($i = 0; $i < $_REQUEST['values']; ++$i) {
609
                    if (!isset($_REQUEST['value'][$i])) {
610
                        $_REQUEST['value'][$i] = '';
611
                    }
612
613
                    echo "\t<tr>\n\t\t<td>", $i + 1, '.&nbsp;</td>'.PHP_EOL;
614
                    echo "\t\t<td><input name=\"value[{$i}]\" size=\"16\" maxlength=\"{$data->_maxNameLen}\" value=\"",
615
                    htmlspecialchars($_REQUEST['value'][$i]), "\" /></td>\n\t</tr>".PHP_EOL;
616
                }
617
                echo '</table>'.PHP_EOL;
618
                echo '<p><input type="hidden" name="action" value="create_enum" />'.PHP_EOL;
619
                echo '<input type="hidden" name="stage" value="3" />'.PHP_EOL;
620
                echo $this->misc->form;
621
                echo '<input type="hidden" name="name" value="', htmlspecialchars($_REQUEST['name']), '" />'.PHP_EOL;
622
                echo '<input type="hidden" name="values" value="', htmlspecialchars($_REQUEST['values']), '" />'.PHP_EOL;
623
                echo '<input type="hidden" name="typcomment" value="', htmlspecialchars($_REQUEST['typcomment']), '" />'.PHP_EOL;
624
                echo "<input type=\"submit\" value=\"{$this->lang['strcreate']}\" />".PHP_EOL;
625
                echo "<input type=\"submit\" name=\"cancel\" value=\"{$this->lang['strcancel']}\" /></p>".PHP_EOL;
626
                echo '</form>'.PHP_EOL;
627
628
                break;
629
            case 3:
630
631
                // Check inputs
632
                $values = trim($_REQUEST['values']);
633
                if ('' == trim($_REQUEST['name'])) {
634
                    $_REQUEST['stage'] = 1;
635
                    $this->doCreateEnum($this->lang['strtypeneedsname']);
636
637
                    return;
638
                }
639
                if ('' == $values || !is_numeric($values) || $values != (int) $values || $values <= 0) {
640
                    $_REQUEST['stage'] = 1;
641
                    $this->doCreateEnum($this->lang['strtypeneedsvals']);
642
643
                    return;
644
                }
645
646
                $status = $data->createEnumType($_REQUEST['name'], $_REQUEST['value'], $_REQUEST['typcomment']);
647
648
                if (0 == $status) {
649
                    $this->doDefault($this->lang['strtypecreated']);
650
                } elseif ($status == -1) {
651
                    $_REQUEST['stage'] = 2;
652
                    $this->doCreateEnum($this->lang['strtypeneedsvalue']);
653
654
                    return;
655
                } else {
656
                    $_REQUEST['stage'] = 2;
657
                    $this->doCreateEnum($this->lang['strtypecreatedbad']);
658
659
                    return;
660
                }
661
662
                break;
663
            default:
664
                echo "<p>{$this->lang['strinvalidparam']}</p>".PHP_EOL;
665
        }
666
    }
667
668
    /**
669
     * Displays a screen where they can enter a new type.
670
     *
671
     * @param mixed $msg
672
     */
673
    public function doCreate($msg = '')
674
    {
675
        $data = $this->misc->getDatabaseAccessor();
676
677
        $this->coalesceArr($_POST, 'typname', '');
678
679
        $this->coalesceArr($_POST, 'typin', '');
680
681
        $this->coalesceArr($_POST, 'typout', '');
682
683
        $this->coalesceArr($_POST, 'typlen', '');
684
685
        $this->coalesceArr($_POST, 'typdef', '');
686
687
        $this->coalesceArr($_POST, 'typelem', '');
688
689
        $this->coalesceArr($_POST, 'typdelim', '');
690
691
        $this->coalesceArr($_POST, 'typalign', $data->typAlignDef);
692
693
        $this->coalesceArr($_POST, 'typstorage', $data->typStorageDef);
694
695
        // Retrieve all functions and types in the database
696
        $funcs = $data->getFunctions(true);
697
        $types = $data->getTypes(true);
698
699
        $this->printTrail('schema');
700
        $this->printTitle($this->lang['strcreatetype'], 'pg.type.create');
701
        $this->printMsg($msg);
702
703
        echo '<form action="'.\SUBFOLDER.'/src/views/types" method="post">'.PHP_EOL;
704
        echo '<table>'.PHP_EOL;
705
        echo "<tr><th class=\"data left required\">{$this->lang['strname']}</th>".PHP_EOL;
706
        echo "<td class=\"data1\"><input name=\"typname\" size=\"32\" maxlength=\"{$data->_maxNameLen}\" value=\"",
707
        htmlspecialchars($_POST['typname']), '" /></td></tr>'.PHP_EOL;
708
        echo "<tr><th class=\"data left required\">{$this->lang['strinputfn']}</th>".PHP_EOL;
709
        echo '<td class="data1"><select name="typin">';
710
        while (!$funcs->EOF) {
711
            $proname = htmlspecialchars($funcs->fields['proname']);
712
            echo "<option value=\"{$proname}\"",
713
            ($proname == $_POST['typin']) ? ' selected="selected"' : '', ">{$proname}</option>".PHP_EOL;
714
            $funcs->moveNext();
715
        }
716
        echo '</select></td></tr>'.PHP_EOL;
717
        echo "<tr><th class=\"data left required\">{$this->lang['stroutputfn']}</th>".PHP_EOL;
718
        echo '<td class="data1"><select name="typout">';
719
        $funcs->moveFirst();
720
        while (!$funcs->EOF) {
721
            $proname = htmlspecialchars($funcs->fields['proname']);
722
            echo "<option value=\"{$proname}\"",
723
            ($proname == $_POST['typout']) ? ' selected="selected"' : '', ">{$proname}</option>".PHP_EOL;
724
            $funcs->moveNext();
725
        }
726
        echo '</select></td></tr>'.PHP_EOL;
727
        echo '<tr><th class="data left'.(version_compare($data->major_version, '7.4', '<') ? ' required' : '')."\">{$this->lang['strlength']}</th>".PHP_EOL;
728
        echo '<td class="data1"><input name="typlen" size="8" value="',
729
        htmlspecialchars($_POST['typlen']), '" /></td></tr>';
730
        echo "<tr><th class=\"data left\">{$this->lang['strdefault']}</th>".PHP_EOL;
731
        echo '<td class="data1"><input name="typdef" size="8" value="',
732
        htmlspecialchars($_POST['typdef']), '" /></td></tr>';
733
        echo "<tr><th class=\"data left\">{$this->lang['strelement']}</th>".PHP_EOL;
734
        echo '<td class="data1"><select name="typelem">';
735
        echo '<option value=""></option>'.PHP_EOL;
736
        while (!$types->EOF) {
737
            $currname = htmlspecialchars($types->fields['typname']);
738
            echo "<option value=\"{$currname}\"",
739
            ($currname == $_POST['typelem']) ? ' selected="selected"' : '', ">{$currname}</option>".PHP_EOL;
740
            $types->moveNext();
741
        }
742
        echo '</select></td></tr>'.PHP_EOL;
743
        echo "<tr><th class=\"data left\">{$this->lang['strdelimiter']}</th>".PHP_EOL;
744
        echo '<td class="data1"><input name="typdelim" size="1" maxlength="1" value="',
745
        htmlspecialchars($_POST['typdelim']), '" /></td></tr>';
746
        echo "<tr><th class=\"data left\"><label for=\"typbyval\">{$this->lang['strpassbyval']}</label></th>".PHP_EOL;
747
        echo '<td class="data1"><input type="checkbox" id="typbyval" name="typbyval"',
748
        isset($_POST['typbyval']) ? ' checked="checked"' : '', ' /></td></tr>';
749
        echo "<tr><th class=\"data left\">{$this->lang['stralignment']}</th>".PHP_EOL;
750
        echo '<td class="data1"><select name="typalign">';
751
        foreach ($data->typAligns as $v) {
752
            echo "<option value=\"{$v}\"",
753
            ($v == $_POST['typalign']) ? ' selected="selected"' : '', ">{$v}</option>".PHP_EOL;
754
        }
755
        echo '</select></td></tr>'.PHP_EOL;
756
        echo "<tr><th class=\"data left\">{$this->lang['strstorage']}</th>".PHP_EOL;
757
        echo '<td class="data1"><select name="typstorage">';
758
        foreach ($data->typStorages as $v) {
759
            echo "<option value=\"{$v}\"",
760
            ($v == $_POST['typstorage']) ? ' selected="selected"' : '', ">{$v}</option>".PHP_EOL;
761
        }
762
        echo '</select></td></tr>'.PHP_EOL;
763
        echo '</table>'.PHP_EOL;
764
        echo '<p><input type="hidden" name="action" value="save_create" />'.PHP_EOL;
765
        echo $this->misc->form;
766
        echo "<input type=\"submit\" value=\"{$this->lang['strcreate']}\" />".PHP_EOL;
767
        echo "<input type=\"submit\" name=\"cancel\" value=\"{$this->lang['strcancel']}\" /></p>".PHP_EOL;
768
        echo '</form>'.PHP_EOL;
769
    }
770
771
    /**
772
     * Actually creates the new type in the database.
773
     */
774
    public function doSaveCreate()
775
    {
776
        $data = $this->misc->getDatabaseAccessor();
777
778
        // Check that they've given a name and a length.
779
        // Note: We're assuming they've given in and out functions here
780
        // which might be unwise...
781
        if ('' == $_POST['typname']) {
782
            $this->doCreate($this->lang['strtypeneedsname']);
783
        } elseif ('' == $_POST['typlen']) {
784
            $this->doCreate($this->lang['strtypeneedslen']);
785
        } else {
786
            $status = $data->createType(
787
                $_POST['typname'],
788
                $_POST['typin'],
789
                $_POST['typout'],
790
                $_POST['typlen'],
791
                $_POST['typdef'],
792
                $_POST['typelem'],
793
                $_POST['typdelim'],
794
                isset($_POST['typbyval']),
795
                $_POST['typalign'],
796
                $_POST['typstorage']
797
            );
798
            if (0 == $status) {
799
                $this->doDefault($this->lang['strtypecreated']);
800
            } else {
801
                $this->doCreate($this->lang['strtypecreatedbad']);
802
            }
803
        }
804
    }
805
}
806