Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 21 additions & 10 deletions libraries/classes/Table/ColumnsDefinition.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,13 @@
use function in_array;
use function intval;
use function is_array;
use function mb_strlen;
use function mb_strtoupper;
use function preg_quote;
use function preg_replace;
use function rtrim;
use function str_ends_with;
use function str_starts_with;
use function stripcslashes;
use function substr;
use function trim;
Expand Down Expand Up @@ -497,9 +500,10 @@ public static function displayForm(
* Set default type and default value according to the column metadata
*
* @param array $columnMeta Column Metadata
* @phpstan-param array<string, string|null> $columnMeta
* @phpstan-param array{Default: string|null, Null: 'YES'|'NO', Type: string} $columnMeta
*
* @return non-empty-array<array-key, mixed>
* @return non-empty-array<string, string>
* @psalm-return array{DefaultType: string, DefaultValue: string}
*/
public static function decorateColumnMetaDefault(array $columnMeta): array
{
Expand All @@ -510,10 +514,9 @@ public static function decorateColumnMetaDefault(array $columnMeta): array

switch ($columnMeta['Default']) {
case null:
if ($columnMeta['Null'] === 'YES') {
$metaDefault['DefaultType'] = 'NULL';
} else {
$metaDefault['DefaultType'] = 'NONE';
// Could be null or empty string here
if ($columnMeta['Default'] === null) {
$metaDefault['DefaultType'] = $columnMeta['Null'] === 'YES' ? 'NULL' : 'NONE';
}

break;
Expand All @@ -528,11 +531,19 @@ public static function decorateColumnMetaDefault(array $columnMeta): array

break;
default:
$metaDefault['DefaultValue'] = $columnMeta['Default'];

if (substr((string) $columnMeta['Type'], -4) === 'text') {
$textDefault = substr($columnMeta['Default'], 1, -1);
$metaDefault['Default'] = stripcslashes($textDefault);
if (
mb_strlen($columnMeta['Default']) >= 2 &&
str_starts_with($columnMeta['Default'], "'") &&
str_ends_with($columnMeta['Default'], "'")
) {
$textDefault = substr($columnMeta['Default'], 1, -1);
$metaDefault['DefaultValue'] = stripcslashes($textDefault);
} else {
$metaDefault['DefaultValue'] = $columnMeta['Default'];
}
} else {
$metaDefault['DefaultValue'] = $columnMeta['Default'];
}

break;
Expand Down
7 changes: 6 additions & 1 deletion phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -35565,6 +35565,11 @@ parameters:
count: 2
path: libraries/classes/Table/ColumnsDefinition.php

-
message: "#^Casting to string something that's already string\\.$#"
count: 1
path: libraries/classes/Table/ColumnsDefinition.php

-
message: "#^Construct empty\\(\\) is not allowed\\. Use more strict comparison\\.$#"
count: 2
Expand Down Expand Up @@ -35596,7 +35601,7 @@ parameters:
path: libraries/classes/Table/ColumnsDefinition.php

-
message: "#^Parameter \\#1 \\$columnMeta of static method PhpMyAdmin\\\\Table\\\\ColumnsDefinition\\:\\:decorateColumnMetaDefault\\(\\) expects array\\<string, string\\|null\\>, mixed given\\.$#"
message: "#^Parameter \\#1 \\$columnMeta of static method PhpMyAdmin\\\\Table\\\\ColumnsDefinition\\:\\:decorateColumnMetaDefault\\(\\) expects array\\{Default\\: string\\|null, Null\\: 'NO'\\|'YES', Type\\: string\\}, mixed given\\.$#"
count: 1
path: libraries/classes/Table/ColumnsDefinition.php

Expand Down
3 changes: 3 additions & 0 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13459,6 +13459,9 @@
<PossiblyInvalidCast occurrences="1">
<code>$_POST['after_field']</code>
</PossiblyInvalidCast>
<RedundantCastGivenDocblockType occurrences="1">
<code>(string) $columnMeta['Type']</code>
</RedundantCastGivenDocblockType>
</file>
<file src="libraries/classes/Table/Indexes.php">
<PossiblyInvalidArgument occurrences="1">
Expand Down
81 changes: 68 additions & 13 deletions test/classes/Table/ColumnsDefinitionTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ class ColumnsDefinitionTest extends AbstractTestCase
*
* @param array $columnMeta column metadata
* @param array $expected expected result
* @phpstan-param array<string, string|null> $columnMeta
* @phpstan-param array<string, string> $expected
* @phpstan-param array{Default: string|null, Null: 'YES'|'NO', Type: string} $columnMeta
* @phpstan-param array{DefaultType: string, DefaultValue: string} $expected
*
* @dataProvider providerColumnMetaDefault
*/
Expand All @@ -33,15 +33,19 @@ public function testDecorateColumnMetaDefault(array $columnMeta, array $expected
* Data provider for testDecorateColumnMetaDefault
*
* @return array
* @psalm-return array<string, array{array<string, string|null>, array<string, string>}>
* @psalm-return array<string, array{
* array{Default: string|null, Null: 'YES'|'NO', Type: string},
* array{DefaultType: string, DefaultValue: string},
* }>
*/
public static function providerColumnMetaDefault(): array
{
return [
'when Default is null and Null is YES' => [
[
'Default' => null,
'Type' => 'int',
'Null' => 'YES',
'Default' => null,
],
[
'DefaultType' => 'NULL',
Expand All @@ -50,63 +54,114 @@ public static function providerColumnMetaDefault(): array
],
'when Default is null and Null is NO' => [
[
'Default' => null,
'Type' => 'int',
'Null' => 'NO',
'Default' => null,
],
[
'DefaultType' => 'NONE',
'DefaultValue' => '',
],
],
'when Default is CURRENT_TIMESTAMP' => [
['Default' => 'CURRENT_TIMESTAMP'],
[
'Type' => 'timestamp',
'Null' => 'NO',
'Default' => 'CURRENT_TIMESTAMP',
],
[
'DefaultType' => 'CURRENT_TIMESTAMP',
'DefaultValue' => '',
],
],
'when Default is current_timestamp' => [
['Default' => 'current_timestamp()'],
[
'Type' => 'datetime',
'Null' => 'NO',
'Default' => 'current_timestamp()',
],
[
'DefaultType' => 'CURRENT_TIMESTAMP',
'DefaultValue' => '',
],
],
'when Default is UUID' => [
['Default' => 'UUID'],
[
'Type' => 'UUID',
'Null' => 'NO',
'Default' => 'UUID',
],
[
'DefaultType' => 'UUID',
'DefaultValue' => '',
],
],
'when Default is uuid()' => [
['Default' => 'uuid()'],
[
'Type' => 'UUID',
'Null' => 'YES',
'Default' => 'uuid()',
],
[
'DefaultType' => 'UUID',
'DefaultValue' => '',
],
],
'when Default is anything else and Type is text' => [
[
'Default' => '"some\/thing"',
'Type' => 'text',
'Null' => 'NO',
'Default' => "'some\\/thing'",
],
[
'Default' => 'some/thing',
'DefaultType' => 'USER_DEFINED',
'DefaultValue' => '"some\/thing"',
'DefaultValue' => 'some/thing',
],
],
'when Default is anything else and Type is not text' => [
[
'Default' => '"some\/thing"',
'Type' => 'something',
'Null' => 'NO',
'Default' => '"some\/thing"',
],
[
'DefaultType' => 'USER_DEFINED',
'DefaultValue' => '"some\/thing"',
],
],
'when varchar Default is empty string' => [
[
'Type' => 'varchar(255)',
'Null' => 'YES',
'Default' => '',
],
[
'DefaultType' => 'USER_DEFINED',
'DefaultValue' => '',
],
],
'when longtext Default is empty string' => [
[
'Type' => 'longtext',
'Null' => 'YES',
'Default' => "''",
],
[
'DefaultType' => 'USER_DEFINED',
'DefaultValue' => '',
],
],
'when text type default is an expression' => [
[
'Type' => 'tinytext',
'Null' => 'YES',
'Default' => 'unix_timestamp()',
],
[
'DefaultType' => 'USER_DEFINED',
'DefaultValue' => 'unix_timestamp()',
],
],
];
}
}
Loading