Passed
Pull Request — develop (#200)
by Felipe
06:52 queued 01:49
created

FunctionsController::doEdit()   F

Complexity

Conditions 23
Paths 1537

Size

Total Lines 178
Code Lines 129

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 178
rs 2
c 0
b 0
f 0
cc 23
eloc 129
nc 1537
nop 1

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 v6.0.0-beta.46
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 FunctionsController extends BaseController
17
{
18
    public $table_place      = 'functions-functions';
19
    public $controller_title = 'strfunctions';
20
21
    /**
22
     * Default method to render the controller according to the action parameter.
23
     */
24
    public function render()
25
    {
26
        if ('tree' == $this->action) {
27
            return $this->doTree();
28
        }
29
30
        $header_template = 'header_datatables.twig';
31
        $footer_template = 'footer.twig';
32
        ob_start();
33
        switch ($this->action) {
34
            case 'save_create':
35
                if (isset($_POST['cancel'])) {
36
                    $this->doDefault();
37
                } else {
38
                    $this->doSaveCreate();
39
                }
40
41
                break;
42
            case 'create':
43
                $header_template = 'header_select2.twig';
44
                $this->doCreate();
45
46
                break;
47
            case 'drop':
48
                if (isset($_POST['drop'])) {
49
                    $this->doDrop(false);
50
                } else {
51
                    $this->doDefault();
52
                }
53
54
                break;
55
            case 'confirm_drop':
56
                $this->doDrop(true);
57
58
                break;
59
            case 'save_edit':
60
                if (isset($_POST['cancel'])) {
61
                    $this->doDefault();
62
                } else {
63
                    $this->doSaveEdit();
64
                }
65
66
                break;
67
            case 'edit':
68
                $header_template = 'header_sqledit.twig';
69
                $footer_template = 'footer_sqledit.twig';
70
                $this->doEdit();
71
72
                break;
73
            case 'properties':
74
                $header_template = 'header_highlight.twig';
75
                $this->doProperties();
76
77
                break;
78
            default:
79
                $this->doDefault();
80
81
                break;
82
        }
83
        $output = ob_get_clean();
84
85
        $this->printHeader($this->headerTitle(), null, true, $header_template);
86
        $this->printBody();
87
        echo $output;
88
        $this->printFooter(true, $footer_template);
89
    }
90
91
    /**
92
     * Show default list of functions in the database.
93
     *
94
     * @param mixed $msg
95
     */
96
    public function doDefault($msg = '')
97
    {
98
        $data = $this->misc->getDatabaseAccessor();
99
100
        $this->printTrail('schema');
101
        $this->printTabs('schema', 'functions');
102
        $this->printMsg($msg);
103
104
        $funcs = $data->getFunctions();
105
106
        $columns = [
107
            'function'     => [
108
                'title' => $this->lang['strfunction'],
109
                'field' => Decorator::field('proproto'),
110
                'url'   => \SUBFOLDER . "/redirect/function?action=properties&amp;{$this->misc->href}&amp;",
111
                'vars'  => ['function' => 'proproto', 'function_oid' => 'prooid'],
112
            ],
113
            'returns'      => [
114
                'title' => $this->lang['strreturns'],
115
                'field' => Decorator::field('proreturns'),
116
            ],
117
            'owner'        => [
118
                'title' => $this->lang['strowner'],
119
                'field' => Decorator::field('proowner'),
120
            ],
121
            'proglanguage' => [
122
                'title' => $this->lang['strproglanguage'],
123
                'field' => Decorator::field('prolanguage'),
124
            ],
125
            'actions'      => [
126
                'title' => $this->lang['stractions'],
127
            ],
128
            'comment'      => [
129
                'title' => $this->lang['strcomment'],
130
                'field' => Decorator::field('procomment'),
131
            ],
132
        ];
133
134
        $actions = [
135
            'multiactions' => [
136
                'keycols' => ['function' => 'proproto', 'function_oid' => 'prooid'],
137
                'url'     => 'functions',
138
            ],
139
            'alter'        => [
140
                'content' => $this->lang['stralter'],
141
                'attr'    => [
142
                    'href' => [
143
                        'url'     => 'functions',
144
                        'urlvars' => [
145
                            'action'       => 'edit',
146
                            'function'     => Decorator::field('proproto'),
147
                            'function_oid' => Decorator::field('prooid'),
148
                        ],
149
                    ],
150
                ],
151
            ],
152
            'drop'         => [
153
                'multiaction' => 'confirm_drop',
154
                'content'     => $this->lang['strdrop'],
155
                'attr'        => [
156
                    'href' => [
157
                        'url'     => 'functions',
158
                        'urlvars' => [
159
                            'action'       => 'confirm_drop',
160
                            'function'     => Decorator::field('proproto'),
161
                            'function_oid' => Decorator::field('prooid'),
162
                        ],
163
                    ],
164
                ],
165
            ],
166
            'privileges'   => [
167
                'content' => $this->lang['strprivileges'],
168
                'attr'    => [
169
                    'href' => [
170
                        'url'     => 'privileges',
171
                        'urlvars' => [
172
                            'subject'      => 'function',
173
                            'function'     => Decorator::field('proproto'),
174
                            'function_oid' => Decorator::field('prooid'),
175
                        ],
176
                    ],
177
                ],
178
            ],
179
        ];
180
181
        echo $this->printTable($funcs, $columns, $actions, $this->table_place, $this->lang['strnofunctions']);
182
183
        $this->_printNavLinks('functions-functions');
184
    }
185
186
    private function _printNavLinks($place, $func_full = '')
187
    {
188
        if ($place === 'functions-properties') {
189
            $navlinks = [
190
                'showall' => [
191
                    'attr'    => [
192
                        'href' => [
193
                            'url'     => 'functions',
194
                            'urlvars' => [
195
                                'server'   => $_REQUEST['server'],
196
                                'database' => $_REQUEST['database'],
197
                                'schema'   => $_REQUEST['schema'],
198
                            ],
199
                        ],
200
                    ],
201
                    'content' => $this->lang['strshowallfunctions'],
202
                ],
203
                'alter'   => [
204
                    'attr'    => [
205
                        'href' => [
206
                            'url'     => 'functions',
207
                            'urlvars' => [
208
                                'action'       => 'edit',
209
                                'server'       => $_REQUEST['server'],
210
                                'database'     => $_REQUEST['database'],
211
                                'schema'       => $_REQUEST['schema'],
212
                                'function'     => $_REQUEST['function'],
213
                                'function_oid' => $_REQUEST['function_oid'],
214
                            ],
215
                        ],
216
                    ],
217
                    'content' => $this->lang['stralter'],
218
                ],
219
                'drop'    => [
220
                    'attr'    => [
221
                        'href' => [
222
                            'url'     => 'functions',
223
                            'urlvars' => [
224
                                'action'       => 'confirm_drop',
225
                                'server'       => $_REQUEST['server'],
226
                                'database'     => $_REQUEST['database'],
227
                                'schema'       => $_REQUEST['schema'],
228
                                'function'     => $func_full,
229
                                'function_oid' => $_REQUEST['function_oid'],
230
                            ],
231
                        ],
232
                    ],
233
                    'content' => $this->lang['strdrop'],
234
                ],
235
            ];
236
        } elseif ($place === 'functions-functions') {
237
            $navlinks = [
238
                'createpl'       => [
239
                    'attr'    => [
240
                        'href' => [
241
                            'url'     => 'functions',
242
                            'urlvars' => [
243
                                'action'   => 'create',
244
                                'server'   => $_REQUEST['server'],
245
                                'database' => $_REQUEST['database'],
246
                                'schema'   => $_REQUEST['schema'],
247
                            ],
248
                        ],
249
                    ],
250
                    'content' => $this->lang['strcreateplfunction'],
251
                ],
252
                'createinternal' => [
253
                    'attr'    => [
254
                        'href' => [
255
                            'url'     => 'functions',
256
                            'urlvars' => [
257
                                'action'   => 'create',
258
                                'language' => 'internal',
259
                                'server'   => $_REQUEST['server'],
260
                                'database' => $_REQUEST['database'],
261
                                'schema'   => $_REQUEST['schema'],
262
                            ],
263
                        ],
264
                    ],
265
                    'content' => $this->lang['strcreateinternalfunction'],
266
                ],
267
                'createc'        => [
268
                    'attr'    => [
269
                        'href' => [
270
                            'url'     => 'functions',
271
                            'urlvars' => [
272
                                'action'   => 'create',
273
                                'language' => 'C',
274
                                'server'   => $_REQUEST['server'],
275
                                'database' => $_REQUEST['database'],
276
                                'schema'   => $_REQUEST['schema'],
277
                            ],
278
                        ],
279
                    ],
280
                    'content' => $this->lang['strcreatecfunction'],
281
                ],
282
            ];
283
        } else {
284
            return;
285
        }
286
287
        $this->printNavLinks($navlinks, $place, get_defined_vars());
288
    }
289
290
    /**
291
     * Generate XML for the browser tree.
292
     */
293
    public function doTree()
294
    {
295
        $data = $this->misc->getDatabaseAccessor();
296
297
        $funcs = $data->getFunctions();
298
299
        $proto = Decorator::concat(Decorator::field('proname'), ' (', Decorator::field('proarguments'), ')');
300
301
        $reqvars = $this->misc->getRequestVars('function');
302
303
        $attrs = [
304
            'text'    => $proto,
305
            'icon'    => 'Function',
306
            'toolTip' => Decorator::field('procomment'),
307
            'action'  => Decorator::redirecturl(
308
                'redirect',
309
                $reqvars,
310
                [
311
                    'action'       => 'properties',
312
                    'function'     => $proto,
313
                    'function_oid' => Decorator::field('prooid'),
314
                ]
315
            ),
316
        ];
317
318
        return $this->printTree($funcs, $attrs, 'functions');
319
    }
320
321
    /**
322
     * Function to save after editing a function.
323
     */
324
    public function doSaveEdit()
325
    {
326
        $data = $this->misc->getDatabaseAccessor();
327
328
        $fnlang = strtolower($_POST['original_lang']);
329
330
        if ('c' == $fnlang) {
331
            $def = [$_POST['formObjectFile'], $_POST['formLinkSymbol']];
332
        } elseif ('internal' == $fnlang) {
333
            $def = $_POST['formLinkSymbol'];
334
        } else {
335
            $def = $_POST['formDefinition'];
336
        }
337
        if (!$data->hasFunctionAlterSchema()) {
338
            $_POST['formFuncSchema'] = '';
339
        }
340
341
        $status = $data->setFunction(
342
            $_POST['original_function'],
343
            $_POST['formFunction'],
344
            $_POST['original_arguments'],
345
            $_POST['original_returns'],
346
            $def,
347
            $_POST['original_lang'],
348
            $_POST['formProperties'],
349
            isset($_POST['original_setof']),
350
            $_POST['original_owner'],
351
            $_POST['formFuncOwn'],
352
            $_POST['original_schema'],
353
            $_POST['formFuncSchema'],
354
            isset($_POST['formCost']) ? $_POST['formCost'] : null,
355
            isset($_POST['formRows']) ? $_POST['formRows'] : 0,
356
            $_POST['formComment']
357
        );
358
359
        if (0 == $status) {
360
            // If function has had schema altered, need to change to the new schema
361
            // and reload the browser frame.
362
            if (!empty($_POST['formFuncSchema']) && ($_POST['formFuncSchema'] != $_POST['original_schema'])) {
363
                // Jump them to the new function schema
364
                $this->misc->setCurrentSchema($_POST['formFuncSchema']);
365
                // Force a browser reload
366
                $this->misc->setReloadBrowser(true);
367
            }
368
            $this->doProperties($this->lang['strfunctionupdated']);
369
        } else {
370
            $this->doEdit($this->lang['strfunctionupdatedbad']);
371
        }
372
    }
373
374
    private function _getNamedParamsArgs($data, $fndata)
375
    {
376
        if (isset($fndata->fields['proallarguments'])) {
377
            $args_arr = $data->phpArray($fndata->fields['proallarguments']);
378
        } else {
379
            $args_arr = explode(', ', $fndata->fields['proarguments']);
380
        }
381
        $names_arr     = $data->phpArray($fndata->fields['proargnames']);
382
        $modes_arr     = $data->phpArray($fndata->fields['proargmodes']);
383
        $args          = '';
384
        $args_arr_size = sizeof($args_arr);
385
        for ($i = 0; $i < $args_arr_size; ++$i) {
386
            if (0 != $i) {
387
                $args .= ', ';
388
            }
389
390
            if (isset($modes_arr[$i])) {
391
                switch ($modes_arr[$i]) {
392
                    case 'i':
393
                        $args .= ' IN ';
394
395
                        break;
396
                    case 'o':
397
                        $args .= ' OUT ';
398
399
                        break;
400
                    case 'b':
401
                        $args .= ' INOUT ';
402
403
                        break;
404
                    case 'v':
405
                        $args .= ' VARIADIC ';
406
407
                        break;
408
                    case 't':
409
                        $args .= ' TABLE ';
410
411
                        break;
412
                }
413
            }
414
            if (isset($names_arr[$i]) && '' != $names_arr[$i]) {
415
                $data->fieldClean($names_arr[$i]);
416
                $args .= '"' . $names_arr[$i] . '" ';
417
            }
418
            $args .= $args_arr[$i];
419
        }
420
        return $args;
421
    }
422
423
    /**
424
     * Function to allow editing of a Function.
425
     *
426
     * @param mixed $msg
427
     */
428
    public function doEdit($msg = '')
429
    {
430
        $data = $this->misc->getDatabaseAccessor();
431
432
        $this->printTrail('function');
433
        $this->printTitle($this->lang['stralter'], 'pg.function.alter');
434
        $this->printMsg($msg);
435
436
        $fndata = $data->getFunction($_REQUEST['function_oid']);
437
438
        if ($fndata->recordCount() <= 0) {
439
            echo "<p>{$this->lang['strnodata']}</p>\n";
440
            return;
441
        }
442
        $fndata->fields['proretset'] = $data->phpBool($fndata->fields['proretset']);
443
444
        // Initialise variables
445
        $_POST['formDefinition'] = $this->getPostParam('formDefinition', $fndata->fields['prosrc']);
446
447
        $_POST['formProperties'] = $this->getPostParam('formProperties', $data->getFunctionProperties($fndata->fields));
448
449
        $_POST['formFunction'] = $this->getPostParam('formFunction', $fndata->fields['proname']);
450
451
        $_POST['formComment'] = $this->getPostParam('formComment', $fndata->fields['procomment']);
452
453
        $_POST['formObjectFile'] = $this->getPostParam('formObjectFile', $fndata->fields['probin']);
454
455
        $_POST['formLinkSymbol'] = $this->getPostParam('formLinkSymbol', $fndata->fields['prosrc']);
456
457
        $_POST['formFuncOwn'] = $this->getPostParam('formFuncOwn', $fndata->fields['proowner']);
458
459
        $_POST['formFuncSchema'] = $this->getPostParam('formFuncSchema', $fndata->fields['proschema']);
460
461
        if ($data->hasFunctionCosting()) {
462
            $_POST['formCost'] = $this->getPostParam('formCost', $fndata->fields['procost']);
463
464
            $_POST['formRows'] = $this->getPostParam('formRows', $fndata->fields['prorows']);
465
        }
466
467
        // Deal with named parameters
468
        if ($data->hasNamedParams()) {
469
            $args = $this->_getNamedParamsArgs($data, $fndata);
470
        } else {
471
            $args = $fndata->fields['proarguments'];
472
        }
473
474
        echo '<form action="' . \SUBFOLDER . "/src/views/functions\" method=\"post\">\n";
475
        echo "<table style=\"width: 90%\">\n";
476
        echo "<tr>\n";
477
        echo "<th class=\"data required\">{$this->lang['strschema']}</th>\n";
478
        echo "<th class=\"data required\">{$this->lang['strfunction']}</th>\n";
479
        echo "<th class=\"data\">{$this->lang['strarguments']}</th>\n";
480
        echo "<th class=\"data required\">{$this->lang['strreturns']}</th>\n";
481
        echo "<th class=\"data required\">{$this->lang['strproglanguage']}</th>\n";
482
        echo "</tr>\n";
483
484
        echo "<tr>\n";
485
        echo '<td class="data1">';
486
        echo '<input type="hidden" name="original_schema" value="', htmlspecialchars($fndata->fields['proschema']), "\" />\n";
487
        if ($data->hasFunctionAlterSchema()) {
488
            $schemas = $data->getSchemas();
489
            echo '<select name="formFuncSchema">';
490
            while (!$schemas->EOF) {
491
                $schema = $schemas->fields['nspname'];
492
                echo '<option value="', htmlspecialchars($schema), '"',
493
                ($schema == $_POST['formFuncSchema']) ? ' selected="selected"' : '', '>', htmlspecialchars($schema), "</option>\n";
494
                $schemas->moveNext();
495
            }
496
            echo "</select>\n";
497
        } else {
498
            echo $fndata->fields['proschema'];
499
        }
500
501
        echo "</td>\n";
502
        echo '<td class="data1">';
503
        echo '<input type="hidden" name="original_function" value="', htmlspecialchars($fndata->fields['proname']), "\" />\n";
504
        echo "<input name=\"formFunction\" style=\"width: 100%\" maxlength=\"{$data->_maxNameLen}\" value=\"", htmlspecialchars($_POST['formFunction']), '" />';
505
        echo "</td>\n";
506
507
        echo '<td class="data1">', $this->misc->printVal($args), "\n";
508
        echo '<input type="hidden" name="original_arguments" value="', htmlspecialchars($args), "\" />\n";
509
        echo "</td>\n";
510
511
        echo '<td class="data1">';
512
        if ($fndata->fields['proretset']) {
513
            echo 'setof ';
514
        }
515
516
        echo $this->misc->printVal($fndata->fields['proresult']), "\n";
517
        echo '<input type="hidden" name="original_returns" value="', htmlspecialchars($fndata->fields['proresult']), "\" />\n";
518
        if ($fndata->fields['proretset']) {
519
            echo "<input type=\"hidden\" name=\"original_setof\" value=\"yes\" />\n";
520
        }
521
522
        echo "</td>\n";
523
524
        echo '<td class="data1">', $this->misc->printVal($fndata->fields['prolanguage']), "\n";
525
        echo '<input type="hidden" name="original_lang" value="', htmlspecialchars($fndata->fields['prolanguage']), "\" />\n";
526
        echo "</td>\n";
527
        echo "</tr>\n";
528
529
        $fnlang = strtolower($fndata->fields['prolanguage']);
530
        if ('c' == $fnlang) {
531
            echo "<tr><th class=\"data required\" colspan=\"2\">{$this->lang['strobjectfile']}</th>\n";
532
            echo "<th class=\"data\" colspan=\"2\">{$this->lang['strlinksymbol']}</th></tr>\n";
533
            echo '<tr><td class="data1" colspan="2"><input type="text" name="formObjectFile" style="width:100%" value="',
534
            htmlspecialchars($_POST['formObjectFile']), "\" /></td>\n";
535
            echo '<td class="data1" colspan="2"><input type="text" name="formLinkSymbol" style="width:100%" value="',
536
            htmlspecialchars($_POST['formLinkSymbol']), "\" /></td></tr>\n";
537
        } elseif ('internal' == $fnlang) {
538
            echo "<tr><th class=\"data\" colspan=\"5\">{$this->lang['strlinksymbol']}</th></tr>\n";
539
            echo '<tr><td class="data1" colspan="5"><input type="text" name="formLinkSymbol" style="width:100%" value="',
540
            htmlspecialchars($_POST['formLinkSymbol']), "\" /></td></tr>\n";
541
        } else {
542
            echo "<tr><th class=\"data required\" colspan=\"5\">{$this->lang['strdefinition']}</th></tr>\n";
543
            echo '<tr><td class="data1" colspan="5">';
544
            $textarea_id = ($fnlang === 'sql' || $fnlang === 'plpgsql') ? 'query' : 'formDefinition';
545
            echo '<textarea style="width:100%;" rows="20" cols="50" id="' . $textarea_id . '" name="formDefinition">';
546
            echo htmlspecialchars($_POST['formDefinition']);
547
            echo "</textarea></td></tr>\n";
548
        }
549
550
        // Display function comment
551
        echo "<tr><th class=\"data\" colspan=\"5\">{$this->lang['strcomment']}</th></tr>\n";
552
        echo '<tr><td class="data1" colspan="5">';
553
        echo '<textarea style="width:100%;" name="formComment" rows="3" cols="50">';
554
        echo htmlspecialchars($_POST['formComment']);
555
        echo "</textarea></td></tr>\n";
556
557
        // Display function cost options
558
        if ($data->hasFunctionCosting()) {
559
            echo "<tr><th class=\"data required\" colspan=\"5\">{$this->lang['strfunctioncosting']}</th></tr>\n";
560
            echo "<td class=\"data1\" colspan=\"2\">{$this->lang['strexecutioncost']}: <input name=\"formCost\" size=\"16\" value=\"" .
561
            htmlspecialchars($_POST['formCost']) . '" /></td>';
562
            echo "<td class=\"data1\" colspan=\"2\">{$this->lang['strresultrows']}: <input name=\"formRows\" size=\"16\" value=\"",
563
            htmlspecialchars($_POST['formRows']), '"', (!$fndata->fields['proretset']) ? 'disabled' : '', '/></td>';
564
        }
565
566
        // Display function properties
567
        if (is_array($data->funcprops) && sizeof($data->funcprops) > 0) {
568
            echo "<tr><th class=\"data\" colspan=\"5\">{$this->lang['strproperties']}</th></tr>\n";
569
            echo "<tr><td class=\"data1\" colspan=\"5\">\n";
570
            $i = 0;
571
            foreach ($data->funcprops as $k => $v) {
572
                echo "<select name=\"formProperties[{$i}]\">\n";
573
                foreach ($v as $p) {
574
                    echo '<option value="', htmlspecialchars($p), '"',
575
                    ($_POST['formProperties'][$i] == $p) ? ' selected="selected"' : '',
576
                    '>', $this->misc->printVal($p), "</option>\n";
577
                }
578
                echo "</select><br />\n";
579
                ++$i;
580
            }
581
            echo "</td></tr>\n";
582
        }
583
584
        // function owner
585
        if ($data->hasFunctionAlterOwner()) {
586
            $users = $data->getUsers();
587
            echo "<tr><td class=\"data1\" colspan=\"5\">{$this->lang['strowner']}: <select name=\"formFuncOwn\">";
588
            while (!$users->EOF) {
589
                $uname = $users->fields['usename'];
590
                echo '<option value="', htmlspecialchars($uname), '"',
591
                ($uname == $_POST['formFuncOwn']) ? ' selected="selected"' : '', '>', htmlspecialchars($uname), "</option>\n";
592
                $users->moveNext();
593
            }
594
            echo "</select>\n";
595
            echo '<input type="hidden" name="original_owner" value="', htmlspecialchars($fndata->fields['proowner']), "\" />\n";
596
            echo "</td></tr>\n";
597
        }
598
        echo "</table>\n";
599
        echo "<p><input type=\"hidden\" name=\"action\" value=\"save_edit\" />\n";
600
        echo '<input type="hidden" name="function" value="', htmlspecialchars($_REQUEST['function']), "\" />\n";
601
        echo '<input type="hidden" name="function_oid" value="', htmlspecialchars($_REQUEST['function_oid']), "\" />\n";
602
        echo $this->misc->form;
603
        echo "<input type=\"submit\" value=\"{$this->lang['stralter']}\" />\n";
604
        echo "<input type=\"submit\" name=\"cancel\" value=\"{$this->lang['strcancel']}\" /></p>\n";
605
        echo "</form>\n";
606
    }
607
608
    /**
609
     * Show read only properties of a function.
610
     *
611
     * @param mixed $msg
612
     */
613
    public function doProperties($msg = '')
614
    {
615
        $data = $this->misc->getDatabaseAccessor();
616
617
        $this->printTrail('function');
618
        $this->printTitle($this->lang['strproperties'], 'pg.function');
619
        $this->printMsg($msg);
620
621
        $funcdata  = $data->getFunction($_REQUEST['function_oid']);
622
        $func_full = '';
623
        if ($funcdata->recordCount() > 0) {
624
            // Deal with named parameters
625
            $args = $this->_getPropertiesArgs($funcdata);
626
627
            // Show comment if any
628
            if (null !== $funcdata->fields['procomment']) {
629
                echo '<p class="comment">', $this->misc->printVal($funcdata->fields['procomment']), "</p>\n";
630
            }
631
632
            $funcdata->fields['proretset'] = $data->phpBool($funcdata->fields['proretset']);
633
            $func_full                     = $funcdata->fields['proname'] . '(' . $funcdata->fields['proarguments'] . ')';
634
            echo "<table style=\"width: 90%\">\n";
635
            echo sprintf('<tr><th class="data">%s</th>%s', $this->lang['strfunction'], "\n");
636
            echo sprintf('<th class="data">%s</th>%s', $this->lang['strarguments'], "\n");
637
            echo sprintf('<th class="data">%s</th>%s', $this->lang['strreturns'], "\n");
638
            echo sprintf('<th class="data">%s</th></tr>%s', $this->lang['strproglanguage'], "\n");
639
            echo '<tr><td class="data1">', $this->misc->printVal($funcdata->fields['proname']), "</td>\n";
640
            echo '<td class="data1">', $this->misc->printVal($args), "</td>\n";
641
            echo '<td class="data1">';
642
            if ($funcdata->fields['proretset']) {
643
                echo 'setof ';
644
            }
645
646
            echo $this->misc->printVal($funcdata->fields['proresult']), "</td>\n";
647
            echo '<td class="data1">', $this->misc->printVal($funcdata->fields['prolanguage']), "</td></tr>\n";
648
649
            $fnlang = strtolower($funcdata->fields['prolanguage']);
650
            if ('c' == $fnlang) {
651
                echo "<tr><th class=\"data\" colspan=\"2\">{$this->lang['strobjectfile']}</th>\n";
652
                echo "<th class=\"data\" colspan=\"2\">{$this->lang['strlinksymbol']}</th></tr>\n";
653
                echo '<tr><td class="data1" colspan="2">', $this->misc->printVal($funcdata->fields['probin']), "</td>\n";
654
                echo '<td class="data1" colspan="2">', $this->misc->printVal($funcdata->fields['prosrc']), "</td></tr>\n";
655
            } elseif ('internal' == $fnlang) {
656
                echo "<tr><th class=\"data\" colspan=\"4\">{$this->lang['strlinksymbol']}</th></tr>\n";
657
                echo '<tr><td class="data1" colspan="4">', $this->misc->printVal($funcdata->fields['prosrc']), "</td></tr>\n";
658
            } else {
659
                echo '<tr><td class="data1" colspan="4">';
660
                echo sprintf('<pre><code class="%s hljs">%s</code></pre>', $fnlang, $funcdata->fields['prosrc']);
661
                echo "</td></tr>\n";
662
            }
663
664
            // Display function cost options
665
            if ($data->hasFunctionCosting()) {
666
                echo "<tr><th class=\"data required\" colspan=\"4\">{$this->lang['strfunctioncosting']}</th></tr>\n";
667
                echo "<td class=\"data1\" colspan=\"2\">{$this->lang['strexecutioncost']}: ", $this->misc->printVal($funcdata->fields['procost']), ' </td>';
668
                echo "<td class=\"data1\" colspan=\"2\">{$this->lang['strresultrows']}: ", $this->misc->printVal($funcdata->fields['prorows']), ' </td>';
669
            }
670
671
            // Show flags
672
            if (is_array($data->funcprops) && sizeof($data->funcprops) > 0) {
673
                // Fetch an array of the function properties
674
                $funcprops = $data->getFunctionProperties($funcdata->fields);
675
                echo "<tr><th class=\"data\" colspan=\"4\">{$this->lang['strproperties']}</th></tr>\n";
676
                echo "<tr><td class=\"data1\" colspan=\"4\">\n";
677
                foreach ($funcprops as $v) {
678
                    echo $this->misc->printVal($v), "<br />\n";
679
                }
680
                echo "</td></tr>\n";
681
            }
682
683
            echo "<tr><td class=\"data1\" colspan=\"5\">{$this->lang['strowner']}: ", htmlspecialchars($funcdata->fields['proowner']), "\n";
684
            echo "</td></tr>\n";
685
            echo "</table>\n";
686
        } else {
687
            echo "<p>{$this->lang['strnodata']}</p>\n";
688
        }
689
690
        $this->_printNavLinks('functions-properties', $func_full);
691
    }
692
693
    /**
694
     * Show confirmation of drop and perform actual drop.
695
     *
696
     * @param mixed $confirm
697
     */
698
    public function doDrop($confirm)
699
    {
700
        $data = $this->misc->getDatabaseAccessor();
701
702
        if (empty($_REQUEST['function']) && empty($_REQUEST['ma'])) {
703
            return $this->doDefault($this->lang['strspecifyfunctiontodrop']);
704
        }
705
706
        if ($confirm) {
707
            $this->printTrail('schema');
708
            $this->printTitle($this->lang['strdrop'], 'pg.function.drop');
709
710
            echo '<form action="' . \SUBFOLDER . "/src/views/functions\" method=\"post\">\n";
711
712
            //If multi drop
713
            if (isset($_REQUEST['ma'])) {
714
                foreach ($_REQUEST['ma'] as $v) {
715
                    $a = unserialize(htmlspecialchars_decode($v, ENT_QUOTES));
716
                    echo '<p>', sprintf($this->lang['strconfdropfunction'], $this->misc->printVal($a['function'])), "</p>\n";
717
                    echo '<input type="hidden" name="function[]" value="', htmlspecialchars($a['function']), "\" />\n";
718
                    echo '<input type="hidden" name="function_oid[]" value="', htmlspecialchars($a['function_oid']), "\" />\n";
719
                }
720
            } else {
721
                echo '<p>', sprintf($this->lang['strconfdropfunction'], $this->misc->printVal($_REQUEST['function'])), "</p>\n";
722
                echo '<input type="hidden" name="function" value="', htmlspecialchars($_REQUEST['function']), "\" />\n";
723
                echo '<input type="hidden" name="function_oid" value="', htmlspecialchars($_REQUEST['function_oid']), "\" />\n";
724
            }
725
726
            echo "<input type=\"hidden\" name=\"action\" value=\"drop\" />\n";
727
728
            echo $this->misc->form;
729
            echo "<p><input type=\"checkbox\" id=\"cascade\" name=\"cascade\" /><label for=\"cascade\">{$this->lang['strcascade']}</label></p>\n";
730
            echo "<input type=\"submit\" name=\"drop\" value=\"{$this->lang['strdrop']}\" />\n";
731
            echo "<input type=\"submit\" name=\"cancel\" value=\"{$this->lang['strcancel']}\" />\n";
732
            echo "</form>\n";
733
        } else {
734
            if (is_array($_POST['function_oid'])) {
735
                $msg    = '';
736
                $status = $data->beginTransaction();
737
                if (0 == $status) {
738
                    foreach ($_POST['function_oid'] as $k => $s) {
739
                        $status = $data->dropFunction($s, isset($_POST['cascade']));
740
                        if (0 == $status) {
741
                            $msg .= sprintf('%s: %s<br />', htmlentities($_POST['function'][$k], ENT_QUOTES, 'UTF-8'), $this->lang['strfunctiondropped']);
742
                        } else {
743
                            $data->endTransaction();
744
                            $this->doDefault(sprintf('%s%s: %s<br />', $msg, htmlentities($_POST['function'][$k], ENT_QUOTES, 'UTF-8'), $this->lang['strfunctiondroppedbad']));
745
746
                            return;
747
                        }
748
                    }
749
                }
750
                if (0 == $data->endTransaction()) {
751
                    // Everything went fine, back to the Default page....
752
                    $this->misc->setReloadBrowser(true);
753
                    $this->doDefault($msg);
754
                } else {
755
                    $this->doDefault($this->lang['strfunctiondroppedbad']);
756
                }
757
            } else {
758
                $status = $data->dropFunction($_POST['function_oid'], isset($_POST['cascade']));
759
                if (0 == $status) {
760
                    $this->misc->setReloadBrowser(true);
761
                    $this->doDefault($this->lang['strfunctiondropped']);
762
                } else {
763
                    $this->doDefault($this->lang['strfunctiondroppedbad']);
764
                }
765
            }
766
        }
767
    }
768
769
    /**
770
     * Displays a screen where they can enter a new function.
771
     *
772
     * @param string $msg  message to display
773
     * @param mixed  $szJS
774
     */
775
    public function doCreate($msg = '', $szJS = '')
776
    {
777
        $data = $this->misc->getDatabaseAccessor();
778
779
        $this->printTrail('schema');
780
        $_POST['formFunction'] = $this->getPostParam('formFunction', '');
781
782
        $_POST['formArguments'] = $this->getPostParam('formArguments', '');
783
784
        $_POST['formReturns'] = $this->getPostParam('formReturns', '');
785
786
        $this->coalesceArr($_POST, 'formLanguage', isset($_REQUEST['language']) ? $_REQUEST['language'] : 'sql');
787
788
        $_POST['formDefinition'] = $this->getPostParam('formDefinition', '');
789
790
        $_POST['formObjectFile'] = $this->getPostParam('formObjectFile', '');
791
792
        $_POST['formLinkSymbol'] = $this->getPostParam('formLinkSymbol', '');
793
794
        $_POST['formProperties'] = $this->getPostParam('formProperties', $data->defaultprops);
795
796
        $_POST['formSetOf'] = $this->getPostParam('formSetOf', '');
797
798
        $_POST['formArray'] = $this->getPostParam('formArray', '');
799
800
        $_POST['formCost'] = $this->getPostParam('formCost', '');
801
802
        $_POST['formRows'] = $this->getPostParam('formRows', '');
803
804
        $_POST['formComment'] = $this->getPostParam('formComment', '');
805
806
        $types  = $data->getTypes(true, true, true);
807
        $langs  = $data->getLanguages(true);
808
        $fnlang = strtolower($_POST['formLanguage']);
809
810
        switch ($fnlang) {
811
            case 'c':
812
                $this->printTitle($this->lang['strcreatecfunction'], 'pg.function.create.c');
813
814
                break;
815
            case 'internal':
816
                $this->printTitle($this->lang['strcreateinternalfunction'], 'pg.function.create.internal');
817
818
                break;
819
            default:
820
                $this->printTitle($this->lang['strcreateplfunction'], 'pg.function.create.pl');
821
822
                break;
823
        }
824
        $this->printMsg($msg);
825
826
        // Create string for return type list
827
        $szTypes = '';
828
        while (!$types->EOF) {
829
            $szSelected = '';
830
            if ($types->fields['typname'] == $_POST['formReturns']) {
831
                $szSelected = ' selected="selected"';
832
            }
833
            // this variable is include in the JS code bellow, so we need to ENT_QUOTES
834
            $szTypes .= '<option value="' . htmlspecialchars($types->fields['typname'], ENT_QUOTES) . "\"{$szSelected}>";
835
            $szTypes .= htmlspecialchars($types->fields['typname'], ENT_QUOTES) . '</option>';
836
            $types->moveNext();
837
        }
838
839
        $szFunctionName = "<td class=\"data1\"><input name=\"formFunction\" size=\"16\" maxlength=\"{$data->_maxNameLen}\" value=\"" .
840
        htmlspecialchars($_POST['formFunction']) . '" /></td>';
841
842
        $szArguments = '<td class="data1"><input name="formArguments" style="width:100%;" size="16" value="' .
843
        htmlspecialchars($_POST['formArguments']) . '" /></td>';
844
845
        $szSetOfSelected    = '';
846
        $szNotSetOfSelected = '';
847
        if ('' == $_POST['formSetOf']) {
848
            $szNotSetOfSelected = ' selected="selected"';
849
        } elseif ('SETOF' == $_POST['formSetOf']) {
850
            $szSetOfSelected = ' selected="selected"';
851
        }
852
        $szReturns = '<td class="data1" colspan="2">';
853
        $szReturns .= '<select name="formSetOf">';
854
        $szReturns .= "<option value=\"\"{$szNotSetOfSelected}></option>";
855
        $szReturns .= "<option value=\"SETOF\"{$szSetOfSelected}>SETOF</option>";
856
        $szReturns .= '</select>';
857
858
        $szReturns .= '<select class="select2" name="formReturns">' . $szTypes . '</select>';
859
860
        // Create string array type selector
861
862
        $szArraySelected    = '';
863
        $szNotArraySelected = '';
864
        if ('' == $_POST['formArray']) {
865
            $szNotArraySelected = ' selected="selected"';
866
        } elseif ('[]' == $_POST['formArray']) {
867
            $szArraySelected = ' selected="selected"';
868
        }
869
870
        $szReturns .= '<select name="formArray">';
871
        $szReturns .= "<option value=\"\"{$szNotArraySelected}></option>";
872
        $szReturns .= "<option value=\"[]\"{$szArraySelected}>[ ]</option>";
873
        $szReturns .= "</select>\n</td>";
874
875
        // Create string for language
876
        $szLanguage = '<td class="data1">';
877
        if ('c' == $fnlang || 'internal' == $fnlang) {
878
            $szLanguage .= $_POST['formLanguage'] . "\n";
879
            $szLanguage .= "<input type=\"hidden\" name=\"formLanguage\" value=\"{$_POST['formLanguage']}\" />\n";
880
        } else {
881
            $szLanguage .= "<select name=\"formLanguage\">\n";
882
            while (!$langs->EOF) {
883
                $szSelected = '';
884
                if ($langs->fields['lanname'] == $_POST['formLanguage']) {
885
                    $szSelected = ' selected="selected"';
886
                }
887
                if ('c' != strtolower($langs->fields['lanname']) && 'internal' != strtolower($langs->fields['lanname'])) {
888
                    $szLanguage .= '<option value="' . htmlspecialchars($langs->fields['lanname']) . "\"{$szSelected}>\n" .
889
                    $this->misc->printVal($langs->fields['lanname']) . '</option>';
890
                }
891
892
                $langs->moveNext();
893
            }
894
            $szLanguage .= "</select>\n";
895
        }
896
897
        $szLanguage .= '</td>';
898
        $szJSArguments = "<tr><th class=\"data\" colspan=\"7\">{$this->lang['strarguments']}</th></tr>";
899
        $arrayModes    = ['IN', 'OUT', 'INOUT'];
900
        $szModes       = '<select name="formArgModes[]" style="width:100%;">';
901
        foreach ($arrayModes as $pV) {
902
            $szModes .= "<option value=\"{$pV}\">{$pV}</option>";
903
        }
904
        $szModes .= '</select>';
905
        $szArgReturns = '<select name="formArgArray[]">';
906
        $szArgReturns .= '<option value=""></option>';
907
        $szArgReturns .= '<option value="[]">[]</option>';
908
        $szArgReturns .= '</select>';
909
        $subfolder = \SUBFOLDER;
910
        if (!empty($this->conf['theme'])) {
911
            $szImgPath = \SUBFOLDER . "/assets/images/themes/{$this->conf['theme']}";
912
        } else {
913
            $szImgPath = \SUBFOLDER . '/assets/images/themes/default';
914
        }
915
        if (empty($msg)) {
916
            // $this->prtrace($subfolder);
917
            $szJSTRArg = "<script type=\"text/javascript\" >addArg('{$subfolder}');</script>\n";
918
        } else {
919
            $szJSTRArg = '';
920
        }
921
        $szJSAddTR = "<tr id=\"parent_add_tr\" onclick=\"addArg('{$subfolder}');\" onmouseover=\"this.style.cursor='pointer'\">\n";
922
        $szJSAddTR .= '<td style="text-align: right" colspan="6" class="data3"><table><tr><td class="data3">';
923
        $szJSAddTR .= "<img src=\"{$szImgPath}/AddArguments.png\" alt=\"Add Argument\" /></td>";
924
        $szJSAddTR .= "<td class=\"data3\"><span style=\"font-size: 8pt\">{$this->lang['strargadd']}</span></td></tr></table></td>\n</tr>\n";
925
926
        echo '<script src="' . \SUBFOLDER . "/assets/js/functions.js\" type=\"text/javascript\"></script>
927
		<script type=\"text/javascript\">
928
			//<![CDATA[
929
			var g_types_select = '<select class=\"select2\" name=\"formArgType[]\">{$szTypes}</select>{$szArgReturns}';
930
			var g_modes_select = '{$szModes}';
931
			var g_name = '';
932
			var g_lang_strargremove = '", htmlspecialchars($this->lang['strargremove'], ENT_QUOTES), "';
933
			var g_lang_strargnoargs = '", htmlspecialchars($this->lang['strargnoargs'], ENT_QUOTES), "';
934
			var g_lang_strargenableargs = '", htmlspecialchars($this->lang['strargenableargs'], ENT_QUOTES), "';
935
			var g_lang_strargnorowabove = '", htmlspecialchars($this->lang['strargnorowabove'], ENT_QUOTES), "';
936
			var g_lang_strargnorowbelow = '", htmlspecialchars($this->lang['strargnorowbelow'], ENT_QUOTES), "';
937
			var g_lang_strargremoveconfirm = '", htmlspecialchars($this->lang['strargremoveconfirm'], ENT_QUOTES), "';
938
			var g_lang_strargraise = '", htmlspecialchars($this->lang['strargraise'], ENT_QUOTES), "';
939
			var g_lang_strarglower = '", htmlspecialchars($this->lang['strarglower'], ENT_QUOTES), "';
940
			//]]>
941
		</script>
942
		";
943
        echo '<form action="' . \SUBFOLDER . "/src/views/functions\" method=\"post\">\n";
944
        echo "<table><tbody id=\"args_table\">\n";
945
        echo "<tr><th class=\"data required\">{$this->lang['strname']}</th>\n";
946
        echo "<th class=\"data required\" colspan=\"2\">{$this->lang['strreturns']}</th>\n";
947
        echo "<th class=\"data required\">{$this->lang['strproglanguage']}</th></tr>\n";
948
        echo "<tr>\n";
949
        echo "{$szFunctionName}\n";
950
        echo "{$szReturns}\n";
951
        echo "{$szLanguage}\n";
952
        echo "</tr>\n";
953
        echo "{$szJSArguments}\n";
954
        echo "<tr>\n";
955
        echo "<th class=\"data required\">{$this->lang['strargmode']}</th>\n";
956
        echo "<th class=\"data required\">{$this->lang['strname']}</th>\n";
957
        echo "<th class=\"data required\" colspan=\"2\">{$this->lang['strargtype']}</th>\n";
958
        echo "</tr>\n";
959
        echo "{$szJSAddTR}\n";
960
961
        if ('c' == $fnlang) {
962
            echo "<tr><th class=\"data required\" colspan=\"2\">{$this->lang['strobjectfile']}</th>\n";
963
            echo "<th class=\"data\" colspan=\"2\">{$this->lang['strlinksymbol']}</th></tr>\n";
964
            echo '<tr><td class="data1" colspan="2"><input type="text" name="formObjectFile" style="width:100%" value="',
965
            htmlspecialchars($_POST['formObjectFile']), "\" /></td>\n";
966
            echo '<td class="data1" colspan="2"><input type="text" name="formLinkSymbol" style="width:100%" value="',
967
            htmlspecialchars($_POST['formLinkSymbol']), "\" /></td></tr>\n";
968
        } elseif ('internal' == $fnlang) {
969
            echo "<tr><th class=\"data\" colspan=\"4\">{$this->lang['strlinksymbol']}</th></tr>\n";
970
            echo '<tr><td class="data1" colspan="4"><input type="text" name="formLinkSymbol" style="width:100%" value="',
971
            htmlspecialchars($_POST['formLinkSymbol']), "\" /></td></tr>\n";
972
        } else {
973
            echo "<tr><th class=\"data required\" colspan=\"4\">{$this->lang['strdefinition']}</th></tr>\n";
974
            echo '<tr><td class="data1" colspan="4">';
975
            echo '<textarea style="width:100%;" rows="20" cols="50" name="formDefinition">';
976
            echo htmlspecialchars($_POST['formDefinition']);
977
            echo "</textarea></td></tr>\n";
978
        }
979
980
        // Display function comment
981
        echo "<tr><th class=\"data\" colspan=\"4\">{$this->lang['strcomment']}</th></tr>\n";
982
        echo '<tr><td class="data1" colspan="4"><textarea style="width:100%;" name="formComment" rows="3" cols="50">',
983
        htmlspecialchars($_POST['formComment']), "</textarea></td></tr>\n";
984
985
        // Display function cost options
986
        if ($data->hasFunctionCosting()) {
987
            echo "<tr><th class=\"data required\" colspan=\"4\">{$this->lang['strfunctioncosting']}</th></tr>\n";
988
            echo "<td class=\"data1\" colspan=\"2\">{$this->lang['strexecutioncost']}: <input name=\"formCost\" size=\"16\" value=\"" .
989
            htmlspecialchars($_POST['formCost']) . '" /></td>';
990
            echo "<td class=\"data1\" colspan=\"2\">{$this->lang['strresultrows']}: <input name=\"formRows\" size=\"16\" value=\"" .
991
            htmlspecialchars($_POST['formRows']) . '" /></td>';
992
        }
993
994
        // Display function properties
995
        if (is_array($data->funcprops) && sizeof($data->funcprops) > 0) {
996
            echo "<tr><th class=\"data required\" colspan=\"4\">{$this->lang['strproperties']}</th></tr>\n";
997
            echo "<tr><td class=\"data1\" colspan=\"4\">\n";
998
            $i = 0;
999
            foreach ($data->funcprops as $k => $v) {
1000
                echo "<select name=\"formProperties[{$i}]\">\n";
1001
                foreach ($v as $p) {
1002
                    echo '<option value="', htmlspecialchars($p), '"',
1003
                    ($_POST['formProperties'][$i] == $p) ? ' selected="selected"' : '',
1004
                    '>', $this->misc->printVal($p), "</option>\n";
1005
                }
1006
                echo "</select><br />\n";
1007
                ++$i;
1008
            }
1009
            echo "</td></tr>\n";
1010
        }
1011
        echo "</tbody></table>\n";
1012
        echo $szJSTRArg;
1013
        echo "<p><input type=\"hidden\" name=\"action\" value=\"save_create\" />\n";
1014
        echo $this->misc->form;
1015
        echo "<input type=\"submit\" value=\"{$this->lang['strcreate']}\" />\n";
1016
        echo "<input type=\"submit\" name=\"cancel\" value=\"{$this->lang['strcancel']}\" /></p>\n";
1017
        echo "</form>\n";
1018
        echo $szJS;
1019
    }
1020
1021
    /**
1022
     * Actually creates the new function in the database.
1023
     */
1024
    public function doSaveCreate()
1025
    {
1026
        $data = $this->misc->getDatabaseAccessor();
1027
1028
        $fnlang = strtolower($_POST['formLanguage']);
1029
1030
        if ('c' == $fnlang) {
1031
            $def = [$_POST['formObjectFile'], $_POST['formLinkSymbol']];
1032
        } elseif ('internal' == $fnlang) {
1033
            $def = $_POST['formLinkSymbol'];
1034
        } else {
1035
            $def = $_POST['formDefinition'];
1036
        }
1037
1038
        $szJS = '';
1039
1040
        echo '<script src="' . \SUBFOLDER . '/assets/js/functions.js" type="text/javascript"></script>';
1041
        echo '<script type="text/javascript">' . $this->_buildJSData() . '</script>';
1042
        if (!empty($_POST['formArgName'])) {
1043
            $szJS = $this->_buildJSRows($this->_buildFunctionArguments($_POST));
1044
        } else {
1045
            $subfolder = \SUBFOLDER;
1046
            // $this->prtrace($subfolder);
1047
            $szJS = '<script type="text/javascript" src="' . \SUBFOLDER . '/assets/js/functions.js">noArgsRebuild(addArg("' . $subfolder . '"));</script>';
1048
        }
1049
1050
        $cost = (isset($_POST['formCost'])) ? $_POST['formCost'] : null;
1051
        if ('' == $cost || !is_numeric($cost) || $cost != (int) $cost || $cost < 0) {
1052
            $cost = null;
1053
        }
1054
1055
        $rows = (isset($_POST['formRows'])) ? $_POST['formRows'] : null;
1056
        if ('' == $rows || !is_numeric($rows) || $rows != (int) $rows) {
1057
            $rows = null;
1058
        }
1059
1060
        // Check that they've given a name and a definition
1061
        if ('' == $_POST['formFunction']) {
1062
            $this->doCreate($this->lang['strfunctionneedsname'], $szJS);
1063
        } elseif ('internal' != $fnlang && !$def) {
1064
            $this->doCreate($this->lang['strfunctionneedsdef'], $szJS);
1065
        } else {
1066
            // Append array symbol to type if chosen
1067
            $status = $data->createFunction(
1068
                $_POST['formFunction'],
1069
                empty($_POST['nojs']) ? $this->_buildFunctionArguments($_POST) : $_POST['formArguments'],
1070
                $_POST['formReturns'] . $_POST['formArray'],
1071
                $def,
1072
                $_POST['formLanguage'],
1073
                $_POST['formProperties'],
1074
                'SETOF' == $_POST['formSetOf'],
1075
                $cost,
1076
                $rows,
1077
                $_POST['formComment'],
1078
                false
1079
            );
1080
            if (0 == $status) {
1081
                $this->doDefault($this->lang['strfunctioncreated']);
1082
            } else {
1083
                $this->doCreate($this->lang['strfunctioncreatedbad'], $szJS);
1084
            }
1085
        }
1086
    }
1087
1088
    /**
1089
     * Build out the function arguments string.
1090
     *
1091
     * @param array $arrayVars
1092
     *
1093
     * @return string the imploded array vars
1094
     */
1095
    private function _buildFunctionArguments($arrayVars)
1096
    {
1097
        if (isset($_POST['formArgName'])) {
1098
            $arrayArgs = [];
1099
            foreach ($arrayVars['formArgName'] as $pK => $pV) {
1100
                $arrayArgs[] = $arrayVars['formArgModes'][$pK] . ' ' . trim($pV) . ' ' . trim($arrayVars['formArgType'][$pK]) . $arrayVars['formArgArray'][$pK];
1101
            }
1102
1103
            return implode(',', $arrayArgs);
1104
        }
1105
1106
        return '';
1107
    }
1108
1109
    /**
1110
     * Build out JS to re-create table rows for arguments.
1111
     *
1112
     * @param string $szArgs args to parse
1113
     */
1114
    private function _buildJSRows($szArgs)
1115
    {
1116
        $arrayModes      = ['IN', 'OUT', 'INOUT'];
1117
        $arrayArgs       = explode(',', $szArgs);
1118
        $arrayProperArgs = [];
1119
        $nC              = 0;
1120
        $szReturn        = '';
1121
        $szMode          = [];
1122
        foreach ($arrayArgs as $pV) {
1123
            $arrayWords = explode(' ', $pV);
1124
            if (true === in_array($arrayWords[0], $arrayModes, true)) {
1125
                $szMode = $arrayWords[0];
1126
                array_shift($arrayWords);
1127
            }
1128
            $szArgName = array_shift($arrayWords);
1129
            if (false === strpos($arrayWords[count($arrayWords) - 1], '[]')) {
1130
                $szArgType   = implode(' ', $arrayWords);
1131
                $bArgIsArray = 'false';
1132
            } else {
1133
                $szArgType   = str_replace('[]', '', implode(' ', $arrayWords));
1134
                $bArgIsArray = 'true';
1135
            }
1136
            $arrayProperArgs[] = [$szMode, $szArgName, $szArgType, $bArgIsArray];
1137
            $subfolder         = \SUBFOLDER;
1138
            // $this->prtrace($subfolder);
1139
            $szReturn .= '<script type="text/javascript">';
1140
            $szReturn .= "RebuildArgTR('{$szMode}','{$szArgName}','{$szArgType}',new Boolean({$bArgIsArray},{$subfolder}));";
1141
            $szReturn .= '</script>;';
1142
            ++$nC;
1143
        }
1144
1145
        return $szReturn;
1146
    }
1147
1148
    private function _buildJSData()
1149
    {
1150
        $data = $this->misc->getDatabaseAccessor();
1151
1152
        $arrayModes  = ['IN', 'OUT', 'INOUT'];
1153
        $arrayTypes  = $data->getTypes(true, true, true);
1154
        $arrayPTypes = [];
1155
        $arrayPModes = [];
1156
1157
        while (!$arrayTypes->EOF) {
1158
            $arrayPTypes[] = "'" . $arrayTypes->fields['typname'] . "'";
1159
            $arrayTypes->moveNext();
1160
        }
1161
1162
        foreach ($arrayModes as $pV) {
1163
            $arrayPModes[] = "'{$pV}'";
1164
        }
1165
1166
        $szTypes = 'g_main_types = new Array(' . implode(',', $arrayPTypes) . ');';
1167
        $szModes = 'g_main_modes = new Array(' . implode(',', $arrayPModes) . ');';
1168
1169
        return $szTypes . $szModes;
1170
    }
1171
1172
    /**
1173
     * Get the concatenated arguments for a function.
1174
     *
1175
     * @param \PHPPgAdmin\ADORecordSet $funcdata The funcdata record
1176
     *
1177
     * @return string The arguments of the function
1178
     */
1179
    private function _getPropertiesArgs($funcdata)
1180
    {
1181
        $data = $this->misc->getDatabaseAccessor();
1182
1183
        if ($data->hasNamedParams()) {
1184
            if (isset($funcdata->fields['proallarguments'])) {
1185
                $args_arr = $data->phpArray($funcdata->fields['proallarguments']);
1186
            } else {
1187
                $args_arr = explode(', ', $funcdata->fields['proarguments']);
1188
            }
1189
            $names_arr     = $data->phpArray($funcdata->fields['proargnames']);
1190
            $modes_arr     = $data->phpArray($funcdata->fields['proargmodes']);
1191
            $args          = '';
1192
            $args_arr_size = sizeof($args_arr);
1193
            for ($i = 0; $i < $args_arr_size; ++$i) {
1194
                if (0 != $i) {
1195
                    $args .= ', ';
1196
                }
1197
1198
                if (isset($modes_arr[$i])) {
1199
                    switch ($modes_arr[$i]) {
1200
                        case 'i':
1201
                            $args .= ' IN ';
1202
1203
                            break;
1204
                        case 'o':
1205
                            $args .= ' OUT ';
1206
1207
                            break;
1208
                        case 'b':
1209
                            $args .= ' INOUT ';
1210
1211
                            break;
1212
                        case 'v':
1213
                            $args .= ' VARIADIC ';
1214
1215
                            break;
1216
                        case 't':
1217
                            $args .= ' TABLE ';
1218
1219
                            break;
1220
                    }
1221
                }
1222
                if (isset($names_arr[$i]) && '' != $names_arr[$i]) {
1223
                    $data->fieldClean($names_arr[$i]);
1224
                    $args .= '"' . $names_arr[$i] . '" ';
1225
                }
1226
                $args .= $args_arr[$i];
1227
            }
1228
        } else {
1229
            $args = $funcdata->fields['proarguments'];
1230
        }
1231
1232
        return $args;
1233
    }
1234
}
1235