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