From 874facbad9d3885133621cd4617141d4d80a326a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maur=C3=ADcio=20Meneghini=20Fauth?= Date: Wed, 11 Feb 2026 02:34:12 -0300 Subject: [PATCH] Fix issue after merge 17e34144a1d7fb5ef4494a1cd6c67044228cb865 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: MaurĂ­cio Meneghini Fauth --- phpstan-baseline.neon | 14 ++++---- src/Database/Routines.php | 13 +++----- tests/unit/Database/RoutinesTest.php | 48 ++++++++++++++++++++++++++++ 3 files changed, 60 insertions(+), 15 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 4085eb0527..59a3806b85 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -4588,11 +4588,17 @@ parameters: path: src/Database/Routines.php - - message: '#^Cannot call method has\(\) on PhpMyAdmin\\SqlParser\\Components\\OptionsArray\|null\.$#' + message: '#^Cannot call method get\(\) on PhpMyAdmin\\SqlParser\\Components\\OptionsArray\|null\.$#' identifier: method.nonObject count: 2 path: src/Database/Routines.php + - + message: '#^Cannot call method has\(\) on PhpMyAdmin\\SqlParser\\Components\\OptionsArray\|null\.$#' + identifier: method.nonObject + count: 1 + path: src/Database/Routines.php + - message: '#^Construct empty\(\) is not allowed\. Use more strict comparison\.$#' identifier: empty.notAllowed @@ -4623,12 +4629,6 @@ parameters: count: 4 path: src/Database/Routines.php - - - message: '#^PHPDoc tag @var with type string\|false is not subtype of type bool\.$#' - identifier: varTag.type - count: 2 - path: src/Database/Routines.php - - message: '#^Parameter \#1 \$alias of method PhpMyAdmin\\Types\:\:mapAliasToMysqlType\(\) expects string, mixed given\.$#' identifier: argument.type diff --git a/src/Database/Routines.php b/src/Database/Routines.php index 35799bab76..d9c6ba8d9d 100644 --- a/src/Database/Routines.php +++ b/src/Database/Routines.php @@ -484,14 +484,11 @@ class Routines $retval['item_returnlength'] = implode(',', $stmt->return->parameters); // 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'); - } + $charset = $stmt->return->options->has('CHARSET') + ? $stmt->return->options->get('CHARSET') + : $stmt->return->options->get('CHARACTER SET'); - $retval['item_returnopts_text'] = is_string($charset) ? mb_strtolower($charset) : ''; + $retval['item_returnopts_text'] = mb_strtolower((string) $charset); // Extract numeric options (UNSIGNED, ZEROFILL, UNSIGNED ZEROFILL.) $numericOpts = []; @@ -506,7 +503,7 @@ class Routines $retval['item_returnopts_num'] = implode(' ', $numericOpts); } - $retval['item_definer'] = $stmt->options?->has('DEFINER') ?? false; + $retval['item_definer'] = $stmt->options?->get('DEFINER') ?? ''; $retval['item_definition'] = $body; $retval['item_isdeterministic'] = ''; if ($routine['IS_DETERMINISTIC'] === 'YES') { diff --git a/tests/unit/Database/RoutinesTest.php b/tests/unit/Database/RoutinesTest.php index ffd03868f5..3b6ed53e6d 100644 --- a/tests/unit/Database/RoutinesTest.php +++ b/tests/unit/Database/RoutinesTest.php @@ -542,4 +542,52 @@ class RoutinesTest extends AbstractTestCase $dbiDummy->assertAllQueriesConsumed(); } + + public function testGetDataFromName(): void + { + Current::$database = 'test_db'; + + $dbiDummy = $this->createDbiDummy(); + // phpcs:disable Generic.Files.LineLength.TooLong + $dbiDummy->addResult( + "SELECT SPECIFIC_NAME, ROUTINE_TYPE, DTD_IDENTIFIER, ROUTINE_DEFINITION, IS_DETERMINISTIC, SQL_DATA_ACCESS, ROUTINE_COMMENT, SECURITY_TYPE FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA COLLATE utf8_bin='test_db' AND SPECIFIC_NAME='test_function' AND ROUTINE_TYPE='FUNCTION';", + [['test_function', 'FUNCTION', 'char(50)', "BEGIN RETURN CONCAT('Hello, ', s, '!'); END", 'YES', 'CONTAINS SQL', 'Comment', 'DEFINER']], + ['SPECIFIC_NAME', 'ROUTINE_TYPE', 'DTD_IDENTIFIER', 'ROUTINE_DEFINITION', 'IS_DETERMINISTIC', 'SQL_DATA_ACCESS', 'ROUTINE_COMMENT', 'SECURITY_TYPE'], + ); + $dbiDummy->addResult( + 'SHOW CREATE FUNCTION `test_db`.`test_function`', + [["CREATE DEFINER=`test_user`@`localhost` FUNCTION `test_function`(`s` CHAR(50) CHARSET utf8mb4) RETURNS char(50) CHARSET utf8mb4 COLLATE utf8mb4_uca1400_ai_ci DETERMINISTIC COMMENT 'Comment' BEGIN RETURN CONCAT('Hello, ', s, '!'); END"]], + ['Create Function'], + ); + // phpcs:enable + + $routines = new Routines($this->createDatabaseInterface($dbiDummy), new Config()); + $data = $routines->getDataFromName('test_function', 'FUNCTION'); + $dbiDummy->assertAllQueriesConsumed(); + + self::assertSame([ + 'item_name' => 'test_function', + 'item_type' => 'FUNCTION', + 'item_num_params' => 1, + 'item_param_dir' => [null], + 'item_param_name' => ['s'], + 'item_param_type' => ['CHAR'], + 'item_param_length' => ['50'], + 'item_param_length_arr' => [['50']], + 'item_param_opts_num' => ['utf8mb4'], + 'item_param_opts_text' => ['utf8mb4'], + 'item_type_toggle' => 'PROCEDURE', + 'item_returntype' => 'CHAR', + 'item_returnlength' => '50', + 'item_returnopts_num' => '', + 'item_returnopts_text' => 'utf8mb4', + 'item_definer' => '`test_user`@`localhost`', + 'item_definition' => "BEGIN RETURN CONCAT('Hello, ', s, '!'); END", + 'item_isdeterministic' => " checked='checked'", + 'item_securitytype_definer' => " selected='selected'", + 'item_securitytype_invoker' => '', + 'item_sqldataaccess' => 'CONTAINS SQL', + 'item_comment' => 'Comment', + ], $data); + } }