From a5c12bb28621b1e2770eee71aaddd7de0b8a4b93 Mon Sep 17 00:00:00 2001 From: Declan Boylan Date: Sun, 11 Jan 2026 13:22:08 +0000 Subject: [PATCH] Fix: #19987: Reopening a function removes charset - Psalm & PHPStan issues addressed - Unused ignores from PHPStan baseline removed Signed-off-by: Declan Boylan --- libraries/classes/Database/Routines.php | 33 ++++++++++++++------ phpstan-baseline.neon | 25 --------------- templates/database/routines/editor_form.twig | 2 +- 3 files changed, 25 insertions(+), 35 deletions(-) diff --git a/libraries/classes/Database/Routines.php b/libraries/classes/Database/Routines.php index 586ae9b9ce..51ae75f0a6 100644 --- a/libraries/classes/Database/Routines.php +++ b/libraries/classes/Database/Routines.php @@ -623,19 +623,34 @@ class Routines $retval['item_returnopts_num'] = ''; $retval['item_returnopts_text'] = ''; - if (! empty($routine['DTD_IDENTIFIER'])) { - $options = []; - foreach ($stmt->return->options->options as $opt) { - $options[] = is_string($opt) ? $opt : $opt['value']; - } - + if (! empty($routine['DTD_IDENTIFIER']) && $stmt->return !== null) { $retval['item_returntype'] = $stmt->return->name; $retval['item_returnlength'] = implode(',', $stmt->return->parameters); - $retval['item_returnopts_num'] = implode(' ', $options); - $retval['item_returnopts_text'] = implode(' ', $options); + + // Extract charset (CHARSET or CHARACTER SET) separately from numeric options + /** @var string|false $charset */ + $charset = $stmt->return->options->has('CHARSET'); + if ($charset === false) { + /** @var string|false $charset */ + $charset = $stmt->return->options->has('CHARACTER SET'); + } + + $retval['item_returnopts_text'] = is_string($charset) ? mb_strtolower($charset) : ''; + + // Extract numeric options (UNSIGNED, ZEROFILL, UNSIGNED ZEROFILL.) + $numericOpts = []; + foreach ($stmt->return->options->options as $opt) { + if (! is_string($opt) || ! in_array($opt, $this->numericOptions, true)) { + continue; + } + + $numericOpts[] = $opt; + } + + $retval['item_returnopts_num'] = implode(' ', $numericOpts); } - $retval['item_definer'] = $stmt->options->has('DEFINER'); + $retval['item_definer'] = $stmt->options !== null ? $stmt->options->has('DEFINER') : false; $retval['item_definition'] = $body; $retval['item_isdeterministic'] = ''; if ($routine['IS_DETERMINISTIC'] === 'YES') { diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index f923436a0b..83b3a0cbe0 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -13845,11 +13845,6 @@ parameters: count: 2 path: libraries/classes/Database/Routines.php - - - message: "#^Cannot access offset 'value' on mixed\\.$#" - count: 1 - path: libraries/classes/Database/Routines.php - - message: "#^Cannot access offset \\(float\\|int\\) on mixed\\.$#" count: 6 @@ -13900,21 +13895,6 @@ parameters: count: 9 path: libraries/classes/Database/Routines.php - - - message: "#^Cannot access property \\$name on PhpMyAdmin\\\\SqlParser\\\\Components\\\\DataType\\|null\\.$#" - count: 1 - path: libraries/classes/Database/Routines.php - - - - message: "#^Cannot access property \\$options on PhpMyAdmin\\\\SqlParser\\\\Components\\\\DataType\\|null\\.$#" - count: 1 - path: libraries/classes/Database/Routines.php - - - - message: "#^Cannot access property \\$parameters on PhpMyAdmin\\\\SqlParser\\\\Components\\\\DataType\\|null\\.$#" - count: 1 - path: libraries/classes/Database/Routines.php - - message: "#^Cannot access property \\$types on mixed\\.$#" count: 4 @@ -13925,11 +13905,6 @@ parameters: count: 4 path: libraries/classes/Database/Routines.php - - - message: "#^Cannot call method has\\(\\) on PhpMyAdmin\\\\SqlParser\\\\Components\\\\OptionsArray\\|null\\.$#" - count: 1 - path: libraries/classes/Database/Routines.php - - message: "#^Cannot call method isSuccess\\(\\) on mixed\\.$#" count: 1 diff --git a/templates/database/routines/editor_form.twig b/templates/database/routines/editor_form.twig index f9c0d11c61..0147143c84 100644 --- a/templates/database/routines/editor_form.twig +++ b/templates/database/routines/editor_form.twig @@ -94,7 +94,7 @@ {% for charset in charsets %} - + {% endfor %}