From ed1fef86ca1948568fbb13fb83cc15a048e228c4 Mon Sep 17 00:00:00 2001 From: Johan Vlaar Date: Tue, 25 Aug 2026 13:35:39 +0200 Subject: [PATCH 1/2] [DBAL 32] add platform get name replace --- config/sets/composer-based.php | 4 + .../Fixture/replace.php.inc | 62 ++++++++++++ .../Fixture/skip.php.inc | 32 +++++++ .../PlatformGetNameToInstanceofRectorTest.php | 28 ++++++ .../config/configured_rule.php | 10 ++ .../PlatformGetNameToInstanceofRector.php | 94 +++++++++++++++++++ 6 files changed, 230 insertions(+) create mode 100644 rules-tests/Dbal32/Rector/Identical/PlatformGetNameToInstanceofRector/Fixture/replace.php.inc create mode 100644 rules-tests/Dbal32/Rector/Identical/PlatformGetNameToInstanceofRector/Fixture/skip.php.inc create mode 100644 rules-tests/Dbal32/Rector/Identical/PlatformGetNameToInstanceofRector/PlatformGetNameToInstanceofRectorTest.php create mode 100644 rules-tests/Dbal32/Rector/Identical/PlatformGetNameToInstanceofRector/config/configured_rule.php create mode 100644 rules/Dbal32/Rector/Identical/PlatformGetNameToInstanceofRector.php diff --git a/config/sets/composer-based.php b/config/sets/composer-based.php index 92814890..3cdb058b 100644 --- a/config/sets/composer-based.php +++ b/config/sets/composer-based.php @@ -12,6 +12,7 @@ use Rector\Doctrine\Dbal211\Rector\MethodCall\ExtractArrayArgOnQueryBuilderSelectRector; use Rector\Doctrine\Dbal211\Rector\MethodCall\ReplaceFetchAllMethodCallRector; use Rector\Doctrine\Dbal31\Rector\MethodCall\QueryBuilderExecuteToExecuteQueryOrExecuteStatementRector; +use Rector\Doctrine\Dbal32\Rector\Identical\PlatformGetNameToInstanceofRector; use Rector\Doctrine\Dbal36\Rector\MethodCall\MigrateQueryBuilderResetQueryPartRector; use Rector\Doctrine\Dbal40\Rector\MethodCall\ChangeCompositeExpressionAddMultipleWithWithRector; use Rector\Doctrine\Dbal40\Rector\StmtsAwareInterface\ExecuteQueryParamsToBindValueRector; @@ -71,6 +72,9 @@ // doctrine/dbal 3.1 QueryBuilderExecuteToExecuteQueryOrExecuteStatementRector::class, + // doctrine/dbal 3.2 + PlatformGetNameToInstanceofRector::class, + // doctrine/dbal 4.0 and 4.2 ChangeCompositeExpressionAddMultipleWithWithRector::class, ExecuteQueryParamsToBindValueRector::class, diff --git a/rules-tests/Dbal32/Rector/Identical/PlatformGetNameToInstanceofRector/Fixture/replace.php.inc b/rules-tests/Dbal32/Rector/Identical/PlatformGetNameToInstanceofRector/Fixture/replace.php.inc new file mode 100644 index 00000000..9d3a7943 --- /dev/null +++ b/rules-tests/Dbal32/Rector/Identical/PlatformGetNameToInstanceofRector/Fixture/replace.php.inc @@ -0,0 +1,62 @@ +platform->getName()) { + echo "Is Postgres"; + } + + if ($this->platform->getName() === 'postgresql') { + echo "Is Postgres"; + } + + if ($this->platform->getName() === 'mysql') { + echo "Is MySQL"; + } + + if ($this->platform->getName() === 'unknown_db') { + echo "Is Unknown"; + } + } +} + +----- +platform instanceof \Doctrine\DBAL\Platforms\PostgreSQLPlatform) { + echo "Is Postgres"; + } + + if ($this->platform instanceof \Doctrine\DBAL\Platforms\PostgreSQLPlatform) { + echo "Is Postgres"; + } + + if ($this->platform instanceof \Doctrine\DBAL\Platforms\MySQLPlatform) { + echo "Is MySQL"; + } + + if ($this->platform->getName() === 'unknown_db') { + echo "Is Unknown"; + } + } +} diff --git a/rules-tests/Dbal32/Rector/Identical/PlatformGetNameToInstanceofRector/Fixture/skip.php.inc b/rules-tests/Dbal32/Rector/Identical/PlatformGetNameToInstanceofRector/Fixture/skip.php.inc new file mode 100644 index 00000000..a94a907b --- /dev/null +++ b/rules-tests/Dbal32/Rector/Identical/PlatformGetNameToInstanceofRector/Fixture/skip.php.inc @@ -0,0 +1,32 @@ +getDatabaseType()) { + return; + } + + // Skip: Unknown/custom platform string not in PLATFORM_MAP + if ($someObject->getName() === 'postgresql') { + return; + } + if ('postgresql' === $someObject->getName()) { + return; + } + + // Skip: Comparing getName() result to an integer or non-string + if (123 === $someObject->getName()) { + return; + } + } +} diff --git a/rules-tests/Dbal32/Rector/Identical/PlatformGetNameToInstanceofRector/PlatformGetNameToInstanceofRectorTest.php b/rules-tests/Dbal32/Rector/Identical/PlatformGetNameToInstanceofRector/PlatformGetNameToInstanceofRectorTest.php new file mode 100644 index 00000000..4c61cc2c --- /dev/null +++ b/rules-tests/Dbal32/Rector/Identical/PlatformGetNameToInstanceofRector/PlatformGetNameToInstanceofRectorTest.php @@ -0,0 +1,28 @@ +doTestFile($filePath); + } + + public static function provideData(): Iterator + { + return self::yieldFilesFromDirectory(__DIR__ . '/Fixture'); + } + + public function provideConfigFilePath(): string + { + return __DIR__ . '/config/configured_rule.php'; + } +} diff --git a/rules-tests/Dbal32/Rector/Identical/PlatformGetNameToInstanceofRector/config/configured_rule.php b/rules-tests/Dbal32/Rector/Identical/PlatformGetNameToInstanceofRector/config/configured_rule.php new file mode 100644 index 00000000..f8d269ee --- /dev/null +++ b/rules-tests/Dbal32/Rector/Identical/PlatformGetNameToInstanceofRector/config/configured_rule.php @@ -0,0 +1,10 @@ +rule(PlatformGetNameToInstanceofRector::class); +}; diff --git a/rules/Dbal32/Rector/Identical/PlatformGetNameToInstanceofRector.php b/rules/Dbal32/Rector/Identical/PlatformGetNameToInstanceofRector.php new file mode 100644 index 00000000..f95a6466 --- /dev/null +++ b/rules/Dbal32/Rector/Identical/PlatformGetNameToInstanceofRector.php @@ -0,0 +1,94 @@ + 'Doctrine\DBAL\Platforms\PostgreSQLPlatform', + 'mysql' => 'Doctrine\DBAL\Platforms\MySQLPlatform', + 'sqlite' => 'Doctrine\DBAL\Platforms\SqlitePlatform', + 'oracle' => 'Doctrine\DBAL\Platforms\OraclePlatform', + 'sqlserver' => 'Doctrine\DBAL\Platforms\SQLServerPlatform', + 'mariadb' => 'Doctrine\DBAL\Platforms\MariaDBPlatform', + ]; + + public function getRuleDefinition(): RuleDefinition + { + return new RuleDefinition( + 'Change $platform->getName() === "postgresql" to $platform instanceof PostgreSQLPlatform', + [ + new CodeSample( + "if ('postgresql' === \$this->platform->getName()) {}", + "if (\$this->platform instanceof \Doctrine\DBAL\Platforms\PostgreSQLPlatform) {}" + ), + ] + ); + } + + public function provideComposerPackageConstraint(): ComposerPackageConstraint + { + return new ComposerPackageConstraint('doctrine/dbal', '>= 3.2'); + } + + public function getNodeTypes(): array + { + return [Identical::class, Equal::class]; + } + + /** + * @param Identical|Equal $node + */ + public function refactor(Node $node): ?Node + { + // Handle both: 'postgresql' === $platform->getName() AND $platform->getName() === 'postgresql' + if ($node->left instanceof String_ && $node->right instanceof MethodCall) { + $stringNode = $node->left; + $methodCallNode = $node->right; + } elseif ($node->right instanceof String_ && $node->left instanceof MethodCall) { + $stringNode = $node->right; + $methodCallNode = $node->left; + } else { + return null; + } + + if (! $this->isName($methodCallNode->name, 'getName')) { + return null; + } + + // ONLY apply this if the variable calling getName() is a Doctrine DBAL Platform + if (! $this->isObjectType($methodCallNode->var, new ObjectType('Doctrine\DBAL\Platforms\AbstractPlatform'))) { + return null; + } + + $platformName = $stringNode->value; + if (! isset(self::PLATFORM_MAP[$platformName])) { + return null; + } + + return new Instanceof_( + $methodCallNode->var, + new FullyQualified(self::PLATFORM_MAP[$platformName]) + ); + } +} From 5967dece3639e50bfbdc901b39635e6fcc7aaca7 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Thu, 27 Aug 2026 11:44:09 +0100 Subject: [PATCH 2/2] fix platform map: mssql not sqlserver, add db2, drop mariadb (getName never returns it); broaden fixtures --- .../Fixture/replace.php.inc | 32 +++++++++++++++++++ .../PlatformGetNameToInstanceofRector.php | 21 +++++++----- 2 files changed, 45 insertions(+), 8 deletions(-) diff --git a/rules-tests/Dbal32/Rector/Identical/PlatformGetNameToInstanceofRector/Fixture/replace.php.inc b/rules-tests/Dbal32/Rector/Identical/PlatformGetNameToInstanceofRector/Fixture/replace.php.inc index 9d3a7943..0659bce1 100644 --- a/rules-tests/Dbal32/Rector/Identical/PlatformGetNameToInstanceofRector/Fixture/replace.php.inc +++ b/rules-tests/Dbal32/Rector/Identical/PlatformGetNameToInstanceofRector/Fixture/replace.php.inc @@ -23,6 +23,22 @@ class TestMigration echo "Is MySQL"; } + if ($this->platform->getName() === 'sqlite') { + echo "Is SQLite"; + } + + if ($this->platform->getName() === 'oracle') { + echo "Is Oracle"; + } + + if ($this->platform->getName() === 'mssql') { + echo "Is SQL Server"; + } + + if ($this->platform->getName() === 'db2') { + echo "Is DB2"; + } + if ($this->platform->getName() === 'unknown_db') { echo "Is Unknown"; } @@ -55,6 +71,22 @@ class TestMigration echo "Is MySQL"; } + if ($this->platform instanceof \Doctrine\DBAL\Platforms\SqlitePlatform) { + echo "Is SQLite"; + } + + if ($this->platform instanceof \Doctrine\DBAL\Platforms\OraclePlatform) { + echo "Is Oracle"; + } + + if ($this->platform instanceof \Doctrine\DBAL\Platforms\SQLServerPlatform) { + echo "Is SQL Server"; + } + + if ($this->platform instanceof \Doctrine\DBAL\Platforms\DB2Platform) { + echo "Is DB2"; + } + if ($this->platform->getName() === 'unknown_db') { echo "Is Unknown"; } diff --git a/rules/Dbal32/Rector/Identical/PlatformGetNameToInstanceofRector.php b/rules/Dbal32/Rector/Identical/PlatformGetNameToInstanceofRector.php index f95a6466..8021845a 100644 --- a/rules/Dbal32/Rector/Identical/PlatformGetNameToInstanceofRector.php +++ b/rules/Dbal32/Rector/Identical/PlatformGetNameToInstanceofRector.php @@ -24,19 +24,24 @@ */ final class PlatformGetNameToInstanceofRector extends AbstractRector implements ComposerPackageConstraintInterface { + /** + * Maps the string returned by AbstractPlatform::getName() to its platform class. + * + * @var array + */ private const array PLATFORM_MAP = [ - 'postgresql' => 'Doctrine\DBAL\Platforms\PostgreSQLPlatform', - 'mysql' => 'Doctrine\DBAL\Platforms\MySQLPlatform', - 'sqlite' => 'Doctrine\DBAL\Platforms\SqlitePlatform', - 'oracle' => 'Doctrine\DBAL\Platforms\OraclePlatform', - 'sqlserver' => 'Doctrine\DBAL\Platforms\SQLServerPlatform', - 'mariadb' => 'Doctrine\DBAL\Platforms\MariaDBPlatform', - ]; + 'postgresql' => 'Doctrine\DBAL\Platforms\PostgreSQLPlatform', + 'mysql' => 'Doctrine\DBAL\Platforms\MySQLPlatform', + 'sqlite' => 'Doctrine\DBAL\Platforms\SqlitePlatform', + 'oracle' => 'Doctrine\DBAL\Platforms\OraclePlatform', + 'mssql' => 'Doctrine\DBAL\Platforms\SQLServerPlatform', + 'db2' => 'Doctrine\DBAL\Platforms\DB2Platform', + ]; public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( - 'Change $platform->getName() === "postgresql" to $platform instanceof PostgreSQLPlatform', + 'Change $platform->getName() === "postgresql" to $platform instanceof PostgreSQLPlatform, following the DBAL 3.2 deprecation of AbstractPlatform::getName(), see https://github.com/doctrine/dbal/pull/4755', [ new CodeSample( "if ('postgresql' === \$this->platform->getName()) {}",