diff --git a/composer.json b/composer.json index f41e3813a..f4ef8446d 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,7 @@ "cweagans/composer-patches": "^1.7", "deepdiver/zipstreamer": "^2.0.3", "deepdiver1975/tarstreamer": "^2.1.0", - "doctrine/dbal": "^3.9.1", + "doctrine/dbal": "^3.8.7", "egulias/email-validator": "^4.0.2", "fusonic/opengraph": "^2.3.0", "giggsey/libphonenumber-for-php-lite": "^8.13.12", diff --git a/composer.lock b/composer.lock index 7ebe8a923..f5273e5fb 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "2acd6ae014096370fb40aaa3a5c5bfba", + "content-hash": "05fb424b74258e1c7042d6aab8a8834c", "packages": [ { "name": "aws/aws-crt-php", diff --git a/composer/autoload_classmap.php b/composer/autoload_classmap.php index 8cfb6d0c1..4d686521b 100644 --- a/composer/autoload_classmap.php +++ b/composer/autoload_classmap.php @@ -1416,6 +1416,7 @@ 'Doctrine\\DBAL\\Platforms\\Keywords\\MariaDb102Keywords' => $vendorDir . '/doctrine/dbal/src/Platforms/Keywords/MariaDb102Keywords.php', 'Doctrine\\DBAL\\Platforms\\Keywords\\MySQL57Keywords' => $vendorDir . '/doctrine/dbal/src/Platforms/Keywords/MySQL57Keywords.php', 'Doctrine\\DBAL\\Platforms\\Keywords\\MySQL80Keywords' => $vendorDir . '/doctrine/dbal/src/Platforms/Keywords/MySQL80Keywords.php', + 'Doctrine\\DBAL\\Platforms\\Keywords\\MySQL84Keywords' => $vendorDir . '/doctrine/dbal/src/Platforms/Keywords/MySQL84Keywords.php', 'Doctrine\\DBAL\\Platforms\\Keywords\\MySQLKeywords' => $vendorDir . '/doctrine/dbal/src/Platforms/Keywords/MySQLKeywords.php', 'Doctrine\\DBAL\\Platforms\\Keywords\\OracleKeywords' => $vendorDir . '/doctrine/dbal/src/Platforms/Keywords/OracleKeywords.php', 'Doctrine\\DBAL\\Platforms\\Keywords\\PostgreSQL100Keywords' => $vendorDir . '/doctrine/dbal/src/Platforms/Keywords/PostgreSQL100Keywords.php', @@ -1426,12 +1427,14 @@ 'Doctrine\\DBAL\\Platforms\\Keywords\\SQLServerKeywords' => $vendorDir . '/doctrine/dbal/src/Platforms/Keywords/SQLServerKeywords.php', 'Doctrine\\DBAL\\Platforms\\Keywords\\SQLiteKeywords' => $vendorDir . '/doctrine/dbal/src/Platforms/Keywords/SQLiteKeywords.php', 'Doctrine\\DBAL\\Platforms\\MariaDBPlatform' => $vendorDir . '/doctrine/dbal/src/Platforms/MariaDBPlatform.php', + 'Doctrine\\DBAL\\Platforms\\MariaDb1010Platform' => $vendorDir . '/doctrine/dbal/src/Platforms/MariaDb1010Platform.php', 'Doctrine\\DBAL\\Platforms\\MariaDb1027Platform' => $vendorDir . '/doctrine/dbal/src/Platforms/MariaDb1027Platform.php', 'Doctrine\\DBAL\\Platforms\\MariaDb1043Platform' => $vendorDir . '/doctrine/dbal/src/Platforms/MariaDb1043Platform.php', 'Doctrine\\DBAL\\Platforms\\MariaDb1052Platform' => $vendorDir . '/doctrine/dbal/src/Platforms/MariaDb1052Platform.php', 'Doctrine\\DBAL\\Platforms\\MariaDb1060Platform' => $vendorDir . '/doctrine/dbal/src/Platforms/MariaDb1060Platform.php', 'Doctrine\\DBAL\\Platforms\\MySQL57Platform' => $vendorDir . '/doctrine/dbal/src/Platforms/MySQL57Platform.php', 'Doctrine\\DBAL\\Platforms\\MySQL80Platform' => $vendorDir . '/doctrine/dbal/src/Platforms/MySQL80Platform.php', + 'Doctrine\\DBAL\\Platforms\\MySQL84Platform' => $vendorDir . '/doctrine/dbal/src/Platforms/MySQL84Platform.php', 'Doctrine\\DBAL\\Platforms\\MySQLPlatform' => $vendorDir . '/doctrine/dbal/src/Platforms/MySQLPlatform.php', 'Doctrine\\DBAL\\Platforms\\MySQL\\CollationMetadataProvider' => $vendorDir . '/doctrine/dbal/src/Platforms/MySQL/CollationMetadataProvider.php', 'Doctrine\\DBAL\\Platforms\\MySQL\\CollationMetadataProvider\\CachingCollationMetadataProvider' => $vendorDir . '/doctrine/dbal/src/Platforms/MySQL/CollationMetadataProvider/CachingCollationMetadataProvider.php', @@ -1439,6 +1442,7 @@ 'Doctrine\\DBAL\\Platforms\\MySQL\\Comparator' => $vendorDir . '/doctrine/dbal/src/Platforms/MySQL/Comparator.php', 'Doctrine\\DBAL\\Platforms\\OraclePlatform' => $vendorDir . '/doctrine/dbal/src/Platforms/OraclePlatform.php', 'Doctrine\\DBAL\\Platforms\\PostgreSQL100Platform' => $vendorDir . '/doctrine/dbal/src/Platforms/PostgreSQL100Platform.php', + 'Doctrine\\DBAL\\Platforms\\PostgreSQL120Platform' => $vendorDir . '/doctrine/dbal/src/Platforms/PostgreSQL120Platform.php', 'Doctrine\\DBAL\\Platforms\\PostgreSQL94Platform' => $vendorDir . '/doctrine/dbal/src/Platforms/PostgreSQL94Platform.php', 'Doctrine\\DBAL\\Platforms\\PostgreSQLPlatform' => $vendorDir . '/doctrine/dbal/src/Platforms/PostgreSQLPlatform.php', 'Doctrine\\DBAL\\Platforms\\SQLServer2012Platform' => $vendorDir . '/doctrine/dbal/src/Platforms/SQLServer2012Platform.php', diff --git a/composer/autoload_static.php b/composer/autoload_static.php index 93f632b61..6a8338ef1 100644 --- a/composer/autoload_static.php +++ b/composer/autoload_static.php @@ -1955,6 +1955,7 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'Doctrine\\DBAL\\Platforms\\Keywords\\MariaDb102Keywords' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/Keywords/MariaDb102Keywords.php', 'Doctrine\\DBAL\\Platforms\\Keywords\\MySQL57Keywords' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/Keywords/MySQL57Keywords.php', 'Doctrine\\DBAL\\Platforms\\Keywords\\MySQL80Keywords' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/Keywords/MySQL80Keywords.php', + 'Doctrine\\DBAL\\Platforms\\Keywords\\MySQL84Keywords' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/Keywords/MySQL84Keywords.php', 'Doctrine\\DBAL\\Platforms\\Keywords\\MySQLKeywords' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/Keywords/MySQLKeywords.php', 'Doctrine\\DBAL\\Platforms\\Keywords\\OracleKeywords' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/Keywords/OracleKeywords.php', 'Doctrine\\DBAL\\Platforms\\Keywords\\PostgreSQL100Keywords' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/Keywords/PostgreSQL100Keywords.php', @@ -1965,12 +1966,14 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'Doctrine\\DBAL\\Platforms\\Keywords\\SQLServerKeywords' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/Keywords/SQLServerKeywords.php', 'Doctrine\\DBAL\\Platforms\\Keywords\\SQLiteKeywords' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/Keywords/SQLiteKeywords.php', 'Doctrine\\DBAL\\Platforms\\MariaDBPlatform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/MariaDBPlatform.php', + 'Doctrine\\DBAL\\Platforms\\MariaDb1010Platform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/MariaDb1010Platform.php', 'Doctrine\\DBAL\\Platforms\\MariaDb1027Platform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/MariaDb1027Platform.php', 'Doctrine\\DBAL\\Platforms\\MariaDb1043Platform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/MariaDb1043Platform.php', 'Doctrine\\DBAL\\Platforms\\MariaDb1052Platform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/MariaDb1052Platform.php', 'Doctrine\\DBAL\\Platforms\\MariaDb1060Platform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/MariaDb1060Platform.php', 'Doctrine\\DBAL\\Platforms\\MySQL57Platform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/MySQL57Platform.php', 'Doctrine\\DBAL\\Platforms\\MySQL80Platform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/MySQL80Platform.php', + 'Doctrine\\DBAL\\Platforms\\MySQL84Platform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/MySQL84Platform.php', 'Doctrine\\DBAL\\Platforms\\MySQLPlatform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/MySQLPlatform.php', 'Doctrine\\DBAL\\Platforms\\MySQL\\CollationMetadataProvider' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/MySQL/CollationMetadataProvider.php', 'Doctrine\\DBAL\\Platforms\\MySQL\\CollationMetadataProvider\\CachingCollationMetadataProvider' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/MySQL/CollationMetadataProvider/CachingCollationMetadataProvider.php', @@ -1978,6 +1981,7 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'Doctrine\\DBAL\\Platforms\\MySQL\\Comparator' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/MySQL/Comparator.php', 'Doctrine\\DBAL\\Platforms\\OraclePlatform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/OraclePlatform.php', 'Doctrine\\DBAL\\Platforms\\PostgreSQL100Platform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/PostgreSQL100Platform.php', + 'Doctrine\\DBAL\\Platforms\\PostgreSQL120Platform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/PostgreSQL120Platform.php', 'Doctrine\\DBAL\\Platforms\\PostgreSQL94Platform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/PostgreSQL94Platform.php', 'Doctrine\\DBAL\\Platforms\\PostgreSQLPlatform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/PostgreSQLPlatform.php', 'Doctrine\\DBAL\\Platforms\\SQLServer2012Platform' => __DIR__ . '/..' . '/doctrine/dbal/src/Platforms/SQLServer2012Platform.php', diff --git a/composer/installed.json b/composer/installed.json index 1898b15ad..5f15c06cb 100644 --- a/composer/installed.json +++ b/composer/installed.json @@ -543,17 +543,17 @@ }, { "name": "doctrine/dbal", - "version": "3.8.3", - "version_normalized": "3.8.3.0", + "version": "3.9.1", + "version_normalized": "3.9.1.0", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "db922ba9436b7b18a23d1653a0b41ff2369ca41c" + "reference": "d7dc08f98cba352b2bab5d32c5e58f7e745c11a7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/db922ba9436b7b18a23d1653a0b41ff2369ca41c", - "reference": "db922ba9436b7b18a23d1653a0b41ff2369ca41c", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/d7dc08f98cba352b2bab5d32c5e58f7e745c11a7", + "reference": "d7dc08f98cba352b2bab5d32c5e58f7e745c11a7", "shasum": "" }, "require": { @@ -569,12 +569,12 @@ "doctrine/coding-standard": "12.0.0", "fig/log-test": "^1", "jetbrains/phpstorm-stubs": "2023.1", - "phpstan/phpstan": "1.10.58", - "phpstan/phpstan-strict-rules": "^1.5", - "phpunit/phpunit": "9.6.16", + "phpstan/phpstan": "1.12.0", + "phpstan/phpstan-strict-rules": "^1.6", + "phpunit/phpunit": "9.6.20", "psalm/plugin-phpunit": "0.18.4", "slevomat/coding-standard": "8.13.1", - "squizlabs/php_codesniffer": "3.9.0", + "squizlabs/php_codesniffer": "3.10.2", "symfony/cache": "^5.4|^6.0|^7.0", "symfony/console": "^4.4|^5.4|^6.0|^7.0", "vimeo/psalm": "4.30.0" @@ -582,7 +582,7 @@ "suggest": { "symfony/console": "For helpful console commands such as SQL execution and import of files." }, - "time": "2024-03-03T15:55:06+00:00", + "time": "2024-09-01T13:49:23+00:00", "bin": [ "bin/doctrine-dbal" ], @@ -639,7 +639,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.8.3" + "source": "https://github.com/doctrine/dbal/tree/3.9.1" }, "funding": [ { @@ -709,33 +709,32 @@ }, { "name": "doctrine/event-manager", - "version": "1.2.0", - "version_normalized": "1.2.0.0", + "version": "2.0.1", + "version_normalized": "2.0.1.0", "source": { "type": "git", "url": "https://github.com/doctrine/event-manager.git", - "reference": "95aa4cb529f1e96576f3fda9f5705ada4056a520" + "reference": "b680156fa328f1dfd874fd48c7026c41570b9c6e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/event-manager/zipball/95aa4cb529f1e96576f3fda9f5705ada4056a520", - "reference": "95aa4cb529f1e96576f3fda9f5705ada4056a520", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/b680156fa328f1dfd874fd48c7026c41570b9c6e", + "reference": "b680156fa328f1dfd874fd48c7026c41570b9c6e", "shasum": "" }, "require": { - "doctrine/deprecations": "^0.5.3 || ^1", - "php": "^7.1 || ^8.0" + "php": "^8.1" }, "conflict": { "doctrine/common": "<2.9" }, "require-dev": { - "doctrine/coding-standard": "^9 || ^10", - "phpstan/phpstan": "~1.4.10 || ^1.8.8", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.24" + "doctrine/coding-standard": "^12", + "phpstan/phpstan": "^1.8.8", + "phpunit/phpunit": "^10.5", + "vimeo/psalm": "^5.24" }, - "time": "2022-10-12T20:51:15+00:00", + "time": "2024-05-22T20:47:39+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -784,7 +783,7 @@ ], "support": { "issues": "https://github.com/doctrine/event-manager/issues", - "source": "https://github.com/doctrine/event-manager/tree/1.2.0" + "source": "https://github.com/doctrine/event-manager/tree/2.0.1" }, "funding": [ { diff --git a/composer/installed.php b/composer/installed.php index 36cad38cf..d47444c37 100644 --- a/composer/installed.php +++ b/composer/installed.php @@ -83,9 +83,9 @@ 'dev_requirement' => false, ), 'doctrine/dbal' => array( - 'pretty_version' => '3.8.3', - 'version' => '3.8.3.0', - 'reference' => 'db922ba9436b7b18a23d1653a0b41ff2369ca41c', + 'pretty_version' => '3.9.1', + 'version' => '3.9.1.0', + 'reference' => 'd7dc08f98cba352b2bab5d32c5e58f7e745c11a7', 'type' => 'library', 'install_path' => __DIR__ . '/../doctrine/dbal', 'aliases' => array(), @@ -101,9 +101,9 @@ 'dev_requirement' => false, ), 'doctrine/event-manager' => array( - 'pretty_version' => '1.2.0', - 'version' => '1.2.0.0', - 'reference' => '95aa4cb529f1e96576f3fda9f5705ada4056a520', + 'pretty_version' => '2.0.1', + 'version' => '2.0.1.0', + 'reference' => 'b680156fa328f1dfd874fd48c7026c41570b9c6e', 'type' => 'library', 'install_path' => __DIR__ . '/../doctrine/event-manager', 'aliases' => array(), diff --git a/doctrine/dbal/src/Connection.php b/doctrine/dbal/src/Connection.php index 76b427b5b..b97567060 100644 --- a/doctrine/dbal/src/Connection.php +++ b/doctrine/dbal/src/Connection.php @@ -1317,10 +1317,6 @@ public function setNestTransactionsWithSavepoints($nestTransactionsWithSavepoint throw ConnectionException::mayNotAlterNestedTransactionWithSavepointsInTransaction(); } - if (! $this->getDatabasePlatform()->supportsSavepoints()) { - throw ConnectionException::savepointsNotSupported(); - } - $this->nestTransactionsWithSavepoints = (bool) $nestTransactionsWithSavepoints; } diff --git a/doctrine/dbal/src/Driver/API/MySQL/ExceptionConverter.php b/doctrine/dbal/src/Driver/API/MySQL/ExceptionConverter.php index 87d50aff9..fdfc75a77 100644 --- a/doctrine/dbal/src/Driver/API/MySQL/ExceptionConverter.php +++ b/doctrine/dbal/src/Driver/API/MySQL/ExceptionConverter.php @@ -101,6 +101,7 @@ public function convert(Exception $exception, ?Query $query): DriverException return new ConnectionException($exception, $query); case 2006: + case 4031: return new ConnectionLost($exception, $query); case 1048: diff --git a/doctrine/dbal/src/Driver/AbstractDB2Driver.php b/doctrine/dbal/src/Driver/AbstractDB2Driver.php index 79efb8650..81d84328c 100644 --- a/doctrine/dbal/src/Driver/AbstractDB2Driver.php +++ b/doctrine/dbal/src/Driver/AbstractDB2Driver.php @@ -87,7 +87,7 @@ private function getVersionNumber(string $versionString): string '/^(?:[^\s]+\s)?(?P\d+)\.(?P\d+)\.(?P\d+)/i', $versionString, $versionParts, - ) === 0 + ) !== 1 ) { throw DBALException::invalidPlatformVersionSpecified( $versionString, diff --git a/doctrine/dbal/src/Driver/AbstractMySQLDriver.php b/doctrine/dbal/src/Driver/AbstractMySQLDriver.php index 83159a540..f8c3b3996 100644 --- a/doctrine/dbal/src/Driver/AbstractMySQLDriver.php +++ b/doctrine/dbal/src/Driver/AbstractMySQLDriver.php @@ -8,12 +8,14 @@ use Doctrine\DBAL\Exception; use Doctrine\DBAL\Platforms\AbstractMySQLPlatform; use Doctrine\DBAL\Platforms\AbstractPlatform; +use Doctrine\DBAL\Platforms\MariaDb1010Platform; use Doctrine\DBAL\Platforms\MariaDb1027Platform; use Doctrine\DBAL\Platforms\MariaDb1043Platform; use Doctrine\DBAL\Platforms\MariaDb1052Platform; use Doctrine\DBAL\Platforms\MariaDb1060Platform; use Doctrine\DBAL\Platforms\MySQL57Platform; use Doctrine\DBAL\Platforms\MySQL80Platform; +use Doctrine\DBAL\Platforms\MySQL84Platform; use Doctrine\DBAL\Platforms\MySQLPlatform; use Doctrine\DBAL\Schema\MySQLSchemaManager; use Doctrine\DBAL\VersionAwarePlatformDriver; @@ -40,6 +42,10 @@ public function createDatabasePlatformForVersion($version) if ($mariadb) { $mariaDbVersion = $this->getMariaDbMysqlVersionNumber($version); + if (version_compare($mariaDbVersion, '10.10.0', '>=')) { + return new MariaDb1010Platform(); + } + if (version_compare($mariaDbVersion, '10.6.0', '>=')) { return new MariaDb1060Platform(); } @@ -64,6 +70,20 @@ public function createDatabasePlatformForVersion($version) } } else { $oracleMysqlVersion = $this->getOracleMysqlVersionNumber($version); + + if (version_compare($oracleMysqlVersion, '8.4.0', '>=')) { + if (! version_compare($version, '8.4.0', '>=')) { + Deprecation::trigger( + 'doctrine/orm', + 'https://github.com/doctrine/dbal/pull/5779', + 'Version detection logic for MySQL will change in DBAL 4. ' + . 'Please specify the version as the server reports it, e.g. "8.4.0" instead of "8.4".', + ); + } + + return new MySQL84Platform(); + } + if (version_compare($oracleMysqlVersion, '8', '>=')) { if (! version_compare($version, '8.0.0', '>=')) { Deprecation::trigger( @@ -116,7 +136,7 @@ private function getOracleMysqlVersionNumber(string $versionString): string '/^(?P\d+)(?:\.(?P\d+)(?:\.(?P\d+))?)?/', $versionString, $versionParts, - ) === 0 + ) !== 1 ) { throw Exception::invalidPlatformVersionSpecified( $versionString, @@ -130,6 +150,8 @@ private function getOracleMysqlVersionNumber(string $versionString): string if ($majorVersion === '5' && $minorVersion === '7') { $patchVersion ??= '9'; + } else { + $patchVersion ??= '0'; } return $majorVersion . '.' . $minorVersion . '.' . $patchVersion; @@ -160,7 +182,7 @@ private function getMariaDbMysqlVersionNumber(string $versionString): string '/^(?:5\.5\.5-)?(mariadb-)?(?P\d+)\.(?P\d+)\.(?P\d+)/i', $versionString, $versionParts, - ) === 0 + ) !== 1 ) { throw Exception::invalidPlatformVersionSpecified( $versionString, diff --git a/doctrine/dbal/src/Driver/AbstractPostgreSQLDriver.php b/doctrine/dbal/src/Driver/AbstractPostgreSQLDriver.php index 099630d33..eba309daa 100644 --- a/doctrine/dbal/src/Driver/AbstractPostgreSQLDriver.php +++ b/doctrine/dbal/src/Driver/AbstractPostgreSQLDriver.php @@ -8,6 +8,7 @@ use Doctrine\DBAL\Exception; use Doctrine\DBAL\Platforms\AbstractPlatform; use Doctrine\DBAL\Platforms\PostgreSQL100Platform; +use Doctrine\DBAL\Platforms\PostgreSQL120Platform; use Doctrine\DBAL\Platforms\PostgreSQL94Platform; use Doctrine\DBAL\Platforms\PostgreSQLPlatform; use Doctrine\DBAL\Schema\PostgreSQLSchemaManager; @@ -28,7 +29,7 @@ abstract class AbstractPostgreSQLDriver implements VersionAwarePlatformDriver */ public function createDatabasePlatformForVersion($version) { - if (preg_match('/^(?P\d+)(?:\.(?P\d+)(?:\.(?P\d+))?)?/', $version, $versionParts) === 0) { + if (preg_match('/^(?P\d+)(?:\.(?P\d+)(?:\.(?P\d+))?)?/', $version, $versionParts) !== 1) { throw Exception::invalidPlatformVersionSpecified( $version, '..', @@ -40,6 +41,10 @@ public function createDatabasePlatformForVersion($version) $patchVersion = $versionParts['patch'] ?? 0; $version = $majorVersion . '.' . $minorVersion . '.' . $patchVersion; + if (version_compare($version, '12.0', '>=')) { + return new PostgreSQL120Platform(); + } + if (version_compare($version, '10.0', '>=')) { return new PostgreSQL100Platform(); } diff --git a/doctrine/dbal/src/Driver/OCI8/Middleware/InitializeSession.php b/doctrine/dbal/src/Driver/OCI8/Middleware/InitializeSession.php index 314a04a65..3a356fb31 100644 --- a/doctrine/dbal/src/Driver/OCI8/Middleware/InitializeSession.php +++ b/doctrine/dbal/src/Driver/OCI8/Middleware/InitializeSession.php @@ -26,7 +26,6 @@ public function connect( 'ALTER SESSION SET' . " NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'" . " NLS_TIME_FORMAT = 'HH24:MI:SS'" - . " NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS'" . " NLS_TIMESTAMP_FORMAT = 'YYYY-MM-DD HH24:MI:SS'" . " NLS_TIMESTAMP_TZ_FORMAT = 'YYYY-MM-DD HH24:MI:SS TZH:TZM'" . " NLS_NUMERIC_CHARACTERS = '.,'", diff --git a/doctrine/dbal/src/Platforms/AbstractMySQLPlatform.php b/doctrine/dbal/src/Platforms/AbstractMySQLPlatform.php index 8651b8278..88b45ab29 100644 --- a/doctrine/dbal/src/Platforms/AbstractMySQLPlatform.php +++ b/doctrine/dbal/src/Platforms/AbstractMySQLPlatform.php @@ -1468,4 +1468,30 @@ private function indexAssetsByLowerCaseName(array $assets): array return $result; } + + public function fetchTableOptionsByTable(bool $includeTableName): string + { + $sql = <<<'SQL' + SELECT t.TABLE_NAME, + t.ENGINE, + t.AUTO_INCREMENT, + t.TABLE_COMMENT, + t.CREATE_OPTIONS, + t.TABLE_COLLATION, + ccsa.CHARACTER_SET_NAME + FROM information_schema.TABLES t + INNER JOIN information_schema.COLLATION_CHARACTER_SET_APPLICABILITY ccsa + ON ccsa.COLLATION_NAME = t.TABLE_COLLATION +SQL; + + $conditions = ['t.TABLE_SCHEMA = ?']; + + if ($includeTableName) { + $conditions[] = 't.TABLE_NAME = ?'; + } + + $conditions[] = "t.TABLE_TYPE = 'BASE TABLE'"; + + return $sql . ' WHERE ' . implode(' AND ', $conditions); + } } diff --git a/doctrine/dbal/src/Platforms/AbstractPlatform.php b/doctrine/dbal/src/Platforms/AbstractPlatform.php index 49e131552..928a5a021 100644 --- a/doctrine/dbal/src/Platforms/AbstractPlatform.php +++ b/doctrine/dbal/src/Platforms/AbstractPlatform.php @@ -4693,6 +4693,11 @@ public function columnsEqual(Column $column1, Column $column2): bool return false; } + // If disableTypeComments is true, we do not need to check types, all comparison is already done above + if ($this->disableTypeComments) { + return true; + } + return $column1->getType() === $column2->getType(); } diff --git a/doctrine/dbal/src/Platforms/Keywords/MySQL84Keywords.php b/doctrine/dbal/src/Platforms/Keywords/MySQL84Keywords.php new file mode 100644 index 000000000..b057e71fd --- /dev/null +++ b/doctrine/dbal/src/Platforms/Keywords/MySQL84Keywords.php @@ -0,0 +1,64 @@ +getIndexFieldDeclarationListSQL($index) . ')'; } + private function unquoteSingleIdentifier(string $possiblyQuotedName): string + { + return str_starts_with($possiblyQuotedName, '[') && str_ends_with($possiblyQuotedName, ']') + ? substr($possiblyQuotedName, 1, -1) + : $possiblyQuotedName; + } + /** * Returns the SQL statement for creating a column comment. * @@ -419,23 +429,20 @@ public function getCreatePrimaryKeySQL(Index $index, $table) protected function getCreateColumnCommentSQL($tableName, $columnName, $comment) { if (strpos($tableName, '.') !== false) { - [$schemaSQL, $tableSQL] = explode('.', $tableName); - $schemaSQL = $this->quoteStringLiteral($schemaSQL); - $tableSQL = $this->quoteStringLiteral($tableSQL); + [$schemaName, $tableName] = explode('.', $tableName); } else { - $schemaSQL = "'dbo'"; - $tableSQL = $this->quoteStringLiteral($tableName); + $schemaName = 'dbo'; } return $this->getAddExtendedPropertySQL( 'MS_Description', $comment, 'SCHEMA', - $schemaSQL, + $this->quoteStringLiteral($this->unquoteSingleIdentifier($schemaName)), 'TABLE', - $tableSQL, + $this->quoteStringLiteral($this->unquoteSingleIdentifier($tableName)), 'COLUMN', - $columnName, + $this->quoteStringLiteral($this->unquoteSingleIdentifier($columnName)), ); } @@ -806,23 +813,20 @@ private function alterColumnRequiresDropDefaultConstraint(ColumnDiff $columnDiff protected function getAlterColumnCommentSQL($tableName, $columnName, $comment) { if (strpos($tableName, '.') !== false) { - [$schemaSQL, $tableSQL] = explode('.', $tableName); - $schemaSQL = $this->quoteStringLiteral($schemaSQL); - $tableSQL = $this->quoteStringLiteral($tableSQL); + [$schemaName, $tableName] = explode('.', $tableName); } else { - $schemaSQL = "'dbo'"; - $tableSQL = $this->quoteStringLiteral($tableName); + $schemaName = 'dbo'; } return $this->getUpdateExtendedPropertySQL( 'MS_Description', $comment, 'SCHEMA', - $schemaSQL, + $this->quoteStringLiteral($this->unquoteSingleIdentifier($schemaName)), 'TABLE', - $tableSQL, + $this->quoteStringLiteral($this->unquoteSingleIdentifier($tableName)), 'COLUMN', - $columnName, + $this->quoteStringLiteral($this->unquoteSingleIdentifier($columnName)), ); } @@ -845,22 +849,19 @@ protected function getAlterColumnCommentSQL($tableName, $columnName, $comment) protected function getDropColumnCommentSQL($tableName, $columnName) { if (strpos($tableName, '.') !== false) { - [$schemaSQL, $tableSQL] = explode('.', $tableName); - $schemaSQL = $this->quoteStringLiteral($schemaSQL); - $tableSQL = $this->quoteStringLiteral($tableSQL); + [$schemaName, $tableName] = explode('.', $tableName); } else { - $schemaSQL = "'dbo'"; - $tableSQL = $this->quoteStringLiteral($tableName); + $schemaName = 'dbo'; } return $this->getDropExtendedPropertySQL( 'MS_Description', 'SCHEMA', - $schemaSQL, + $this->quoteStringLiteral($this->unquoteSingleIdentifier($schemaName)), 'TABLE', - $tableSQL, + $this->quoteStringLiteral($this->unquoteSingleIdentifier($tableName)), 'COLUMN', - $columnName, + $this->quoteStringLiteral($this->unquoteSingleIdentifier($columnName)), ); } @@ -907,10 +908,13 @@ public function getAddExtendedPropertySQL( $level2Name = null ) { return 'EXEC sp_addextendedproperty ' . - 'N' . $this->quoteStringLiteral($name) . ', N' . $this->quoteStringLiteral((string) $value) . ', ' . - 'N' . $this->quoteStringLiteral((string) $level0Type) . ', ' . $level0Name . ', ' . - 'N' . $this->quoteStringLiteral((string) $level1Type) . ', ' . $level1Name . ', ' . - 'N' . $this->quoteStringLiteral((string) $level2Type) . ', ' . $level2Name; + 'N' . $this->quoteStringLiteral($name) . ', N' . $this->quoteStringLiteral($value ?? '') . ', ' . + 'N' . $this->quoteStringLiteral($level0Type ?? '') . ', ' . $level0Name . ', ' . + 'N' . $this->quoteStringLiteral($level1Type ?? '') . ', ' . $level1Name . + ($level2Type !== null || $level2Name !== null + ? ', N' . $this->quoteStringLiteral($level2Type ?? '') . ', ' . $level2Name + : '' + ); } /** @@ -941,9 +945,12 @@ public function getDropExtendedPropertySQL( ) { return 'EXEC sp_dropextendedproperty ' . 'N' . $this->quoteStringLiteral($name) . ', ' . - 'N' . $this->quoteStringLiteral((string) $level0Type) . ', ' . $level0Name . ', ' . - 'N' . $this->quoteStringLiteral((string) $level1Type) . ', ' . $level1Name . ', ' . - 'N' . $this->quoteStringLiteral((string) $level2Type) . ', ' . $level2Name; + 'N' . $this->quoteStringLiteral($level0Type ?? '') . ', ' . $level0Name . ', ' . + 'N' . $this->quoteStringLiteral($level1Type ?? '') . ', ' . $level1Name . + ($level2Type !== null || $level2Name !== null + ? ', N' . $this->quoteStringLiteral($level2Type ?? '') . ', ' . $level2Name + : '' + ); } /** @@ -975,10 +982,13 @@ public function getUpdateExtendedPropertySQL( $level2Name = null ) { return 'EXEC sp_updateextendedproperty ' . - 'N' . $this->quoteStringLiteral($name) . ', N' . $this->quoteStringLiteral((string) $value) . ', ' . - 'N' . $this->quoteStringLiteral((string) $level0Type) . ', ' . $level0Name . ', ' . - 'N' . $this->quoteStringLiteral((string) $level1Type) . ', ' . $level1Name . ', ' . - 'N' . $this->quoteStringLiteral((string) $level2Type) . ', ' . $level2Name; + 'N' . $this->quoteStringLiteral($name) . ', N' . $this->quoteStringLiteral($value ?? '') . ', ' . + 'N' . $this->quoteStringLiteral($level0Type ?? '') . ', ' . $level0Name . ', ' . + 'N' . $this->quoteStringLiteral($level1Type ?? '') . ', ' . $level1Name . + ($level2Type !== null || $level2Name !== null + ? ', N' . $this->quoteStringLiteral($level2Type ?? '') . ', ' . $level2Name + : '' + ); } /** @@ -1296,7 +1306,7 @@ public function getAsciiStringTypeDeclarationSQL(array $column): string { $length = $column['length'] ?? null; - if (! isset($column['fixed'])) { + if (empty($column['fixed'])) { return sprintf('VARCHAR(%d)', $length ?? 255); } @@ -1549,12 +1559,14 @@ protected function initializeDoctrineTypeMappings() 'smalldatetime' => Types::DATETIME_MUTABLE, 'smallint' => Types::SMALLINT, 'smallmoney' => Types::INTEGER, + 'sysname' => Types::STRING, 'text' => Types::TEXT, 'time' => Types::TIME_MUTABLE, 'tinyint' => Types::SMALLINT, 'uniqueidentifier' => Types::GUID, 'varbinary' => Types::BINARY, 'varchar' => Types::STRING, + 'xml' => Types::TEXT, ]; } @@ -1765,15 +1777,13 @@ private function generateIdentifierName($identifier): string protected function getCommentOnTableSQL(string $tableName, ?string $comment): string { - return sprintf( - <<<'SQL' - EXEC sys.sp_addextendedproperty @name=N'MS_Description', - @value=N%s, @level0type=N'SCHEMA', @level0name=N'dbo', - @level1type=N'TABLE', @level1name=N%s - SQL - , - $this->quoteStringLiteral((string) $comment), - $this->quoteStringLiteral($tableName), + return $this->getAddExtendedPropertySQL( + 'MS_Description', + $comment, + 'SCHEMA', + $this->quoteStringLiteral('dbo'), + 'TABLE', + $this->quoteStringLiteral($this->unquoteSingleIdentifier($tableName)), ); } diff --git a/doctrine/dbal/src/Platforms/SqlitePlatform.php b/doctrine/dbal/src/Platforms/SqlitePlatform.php index ea9a44413..48c692fdb 100644 --- a/doctrine/dbal/src/Platforms/SqlitePlatform.php +++ b/doctrine/dbal/src/Platforms/SqlitePlatform.php @@ -950,11 +950,6 @@ public function getCreateIndexSQL(Index $index, $table) $name = $index->getQuotedName($this); $columns = $index->getColumns(); - if (strpos($table, '.') !== false) { - [$schema, $table] = explode('.', $table); - $name = $schema . '.' . $name; - } - if (count($columns) === 0) { throw new InvalidArgumentException(sprintf( 'Incomplete or invalid index definition %s on table %s', @@ -967,6 +962,11 @@ public function getCreateIndexSQL(Index $index, $table) return $this->getCreatePrimaryKeySQL($index, $table); } + if (strpos($table, '.') !== false) { + [$schema, $table] = explode('.', $table, 2); + $name = $schema . '.' . $name; + } + $query = 'CREATE ' . $this->getCreateIndexSQLFlags($index) . 'INDEX ' . $name . ' ON ' . $table; $query .= ' (' . $this->getIndexFieldDeclarationListSQL($index) . ')' . $this->getPartialIndexSQL($index); @@ -1150,7 +1150,12 @@ public function getAlterTableSQL(TableDiff $diff) $sql = []; $tableSql = []; if (! $this->onSchemaAlterTable($diff, $tableSql)) { - $dataTable = new Table('__temp__' . $table->getName()); + $tableName = $table->getName(); + if (strpos($tableName, '.') !== false) { + [, $tableName] = explode('.', $tableName, 2); + } + + $dataTable = new Table('__temp__' . $tableName); $newTable = new Table( $table->getQuotedName($this), diff --git a/doctrine/dbal/src/Query/QueryBuilder.php b/doctrine/dbal/src/Query/QueryBuilder.php index f099e756b..4c5d6b8d4 100644 --- a/doctrine/dbal/src/Query/QueryBuilder.php +++ b/doctrine/dbal/src/Query/QueryBuilder.php @@ -1734,7 +1734,7 @@ public function __clone() /** * Enables caching of the results of this query, for given amount of seconds - * and optionally specified witch key to use for the cache entry. + * and optionally specified which key to use for the cache entry. * * @return $this */ diff --git a/doctrine/dbal/src/Result.php b/doctrine/dbal/src/Result.php index fdc7daa94..92235d064 100644 --- a/doctrine/dbal/src/Result.php +++ b/doctrine/dbal/src/Result.php @@ -184,7 +184,7 @@ public function iterateAssociative(): Traversable } /** - * {@inheritDoc} + * @return Traversable * * @throws Exception */ diff --git a/doctrine/dbal/src/Schema/AbstractAsset.php b/doctrine/dbal/src/Schema/AbstractAsset.php index ab8fdec03..6934133ff 100644 --- a/doctrine/dbal/src/Schema/AbstractAsset.php +++ b/doctrine/dbal/src/Schema/AbstractAsset.php @@ -20,7 +20,8 @@ * The abstract asset allows to reset the name of all assets without publishing this to the public userland. * * This encapsulation hack is necessary to keep a consistent state of the database schema. Say we have a list of tables - * array($tableName => Table($tableName)); if you want to rename the table, you have to make sure + * array($tableName => Table($tableName)); if you want to rename the table, you have to make sure this does not get + * recreated during schema migration. */ abstract class AbstractAsset { diff --git a/doctrine/dbal/src/Schema/AbstractSchemaManager.php b/doctrine/dbal/src/Schema/AbstractSchemaManager.php index 7e1fd93ff..2e38bb88c 100644 --- a/doctrine/dbal/src/Schema/AbstractSchemaManager.php +++ b/doctrine/dbal/src/Schema/AbstractSchemaManager.php @@ -31,7 +31,7 @@ * Base class for schema managers. Schema managers are used to inspect and/or * modify the database schema/structure. * - * @template T of AbstractPlatform + * @template-covariant T of AbstractPlatform */ abstract class AbstractSchemaManager { @@ -1740,6 +1740,10 @@ public function getSchemaSearchPaths() */ public function extractDoctrineTypeFromComment($comment, $currentType) { + if ($this->_conn->getConfiguration()->getDisableTypeComments()) { + return $currentType; + } + if ($comment !== null && preg_match('(\(DC2Type:(((?!\)).)+)\))', $comment, $match) === 1) { return $match[1]; } @@ -1757,6 +1761,10 @@ public function extractDoctrineTypeFromComment($comment, $currentType) */ public function removeDoctrineTypeFromComment($comment, $type) { + if ($this->_conn->getConfiguration()->getDisableTypeComments()) { + return $comment; + } + if ($comment === null) { return null; } diff --git a/doctrine/dbal/src/Schema/MySQLSchemaManager.php b/doctrine/dbal/src/Schema/MySQLSchemaManager.php index 3c00d00e2..6e444d213 100644 --- a/doctrine/dbal/src/Schema/MySQLSchemaManager.php +++ b/doctrine/dbal/src/Schema/MySQLSchemaManager.php @@ -557,31 +557,13 @@ protected function selectForeignKeyColumns(string $databaseName, ?string $tableN */ protected function fetchTableOptionsByTable(string $databaseName, ?string $tableName = null): array { - $sql = <<<'SQL' - SELECT t.TABLE_NAME, - t.ENGINE, - t.AUTO_INCREMENT, - t.TABLE_COMMENT, - t.CREATE_OPTIONS, - t.TABLE_COLLATION, - ccsa.CHARACTER_SET_NAME - FROM information_schema.TABLES t - INNER JOIN information_schema.COLLATION_CHARACTER_SET_APPLICABILITY ccsa - ON ccsa.COLLATION_NAME = t.TABLE_COLLATION -SQL; - - $conditions = ['t.TABLE_SCHEMA = ?']; - $params = [$databaseName]; + $sql = $this->_platform->fetchTableOptionsByTable($tableName !== null); + $params = [$databaseName]; if ($tableName !== null) { - $conditions[] = 't.TABLE_NAME = ?'; - $params[] = $tableName; + $params[] = $tableName; } - $conditions[] = "t.TABLE_TYPE = 'BASE TABLE'"; - - $sql .= ' WHERE ' . implode(' AND ', $conditions); - /** @var array> $metadata */ $metadata = $this->_conn->executeQuery($sql, $params) ->fetchAllAssociativeIndexed(); diff --git a/doctrine/dbal/src/Schema/PostgreSQLSchemaManager.php b/doctrine/dbal/src/Schema/PostgreSQLSchemaManager.php index 13fde63b2..3ad313eba 100644 --- a/doctrine/dbal/src/Schema/PostgreSQLSchemaManager.php +++ b/doctrine/dbal/src/Schema/PostgreSQLSchemaManager.php @@ -463,6 +463,7 @@ protected function _getPortableTableColumnDefinition($tableColumn) $length = null; break; + case 'json': case 'text': case '_varchar': case 'varchar': @@ -616,7 +617,7 @@ protected function selectTableColumns(string $databaseName, ?string $tableName = $sql .= ' c.relname AS table_name, n.nspname AS schema_name,'; } - $sql .= <<<'SQL' + $sql .= sprintf(<<<'SQL' a.attnum, quote_ident(a.attname) AS field, t.typname AS type, @@ -632,11 +633,7 @@ protected function selectTableColumns(string $databaseName, ?string $tableName = AND pg_index.indkey[0] = a.attnum AND pg_index.indisprimary = 't' ) AS pri, - (SELECT pg_get_expr(adbin, adrelid) - FROM pg_attrdef - WHERE c.oid = pg_attrdef.adrelid - AND pg_attrdef.adnum=a.attnum - ) AS default, + (%s) AS default, (SELECT pg_description.description FROM pg_description WHERE pg_description.objoid = c.oid AND a.attnum = pg_description.objsubid ) AS comment @@ -651,7 +648,7 @@ protected function selectTableColumns(string $databaseName, ?string $tableName = ON d.objid = c.oid AND d.deptype = 'e' AND d.classid = (SELECT oid FROM pg_class WHERE relname = 'pg_class') -SQL; +SQL, $this->_platform->getDefaultColumnValueSQLSnippet()); $conditions = array_merge([ 'a.attnum > 0', diff --git a/doctrine/dbal/src/Schema/SqliteSchemaManager.php b/doctrine/dbal/src/Schema/SqliteSchemaManager.php index 13f5c5147..0419e934b 100644 --- a/doctrine/dbal/src/Schema/SqliteSchemaManager.php +++ b/doctrine/dbal/src/Schema/SqliteSchemaManager.php @@ -202,7 +202,7 @@ public function listTableForeignKeys($table, $database = null) { $table = $this->normalizeName($table); - $columns = $this->selectForeignKeyColumns('', $table) + $columns = $this->selectForeignKeyColumns($database ?? 'main', $table) ->fetchAllAssociative(); if (count($columns) > 0) { @@ -744,7 +744,7 @@ protected function selectForeignKeyColumns(string $databaseName, ?string $tableN p.* FROM sqlite_master t JOIN pragma_foreign_key_list(t.name) p - ON p."seq" != "-1" + ON p."seq" != '-1' SQL; $conditions = [ diff --git a/doctrine/dbal/src/Tools/Console/Command/ReservedWordsCommand.php b/doctrine/dbal/src/Tools/Console/Command/ReservedWordsCommand.php index e63315466..2204b2e2a 100644 --- a/doctrine/dbal/src/Tools/Console/Command/ReservedWordsCommand.php +++ b/doctrine/dbal/src/Tools/Console/Command/ReservedWordsCommand.php @@ -9,6 +9,7 @@ use Doctrine\DBAL\Platforms\Keywords\MariaDb102Keywords; use Doctrine\DBAL\Platforms\Keywords\MySQL57Keywords; use Doctrine\DBAL\Platforms\Keywords\MySQL80Keywords; +use Doctrine\DBAL\Platforms\Keywords\MySQL84Keywords; use Doctrine\DBAL\Platforms\Keywords\MySQLKeywords; use Doctrine\DBAL\Platforms\Keywords\OracleKeywords; use Doctrine\DBAL\Platforms\Keywords\PostgreSQL100Keywords; @@ -59,6 +60,7 @@ public function __construct(ConnectionProvider $connectionProvider) 'mysql' => new MySQLKeywords(), 'mysql57' => new MySQL57Keywords(), 'mysql80' => new MySQL80Keywords(), + 'mysql84' => new MySQL84Keywords(), 'oracle' => new OracleKeywords(), 'pgsql' => new PostgreSQL94Keywords(), 'pgsql100' => new PostgreSQL100Keywords(), @@ -130,6 +132,7 @@ protected function configure() * mysql * mysql57 * mysql80 + * mysql84 * oracle * pgsql * pgsql100 diff --git a/doctrine/dbal/src/Types/DateTimeTzType.php b/doctrine/dbal/src/Types/DateTimeTzType.php index 1980fd334..b3b5db813 100644 --- a/doctrine/dbal/src/Types/DateTimeTzType.php +++ b/doctrine/dbal/src/Types/DateTimeTzType.php @@ -11,18 +11,19 @@ use function get_class; /** - * DateTime type saving additional timezone information. + * DateTime type accepting additional information about timezone offsets. * * Caution: Databases are not necessarily experts at storing timezone related - * data of dates. First, of all the supported vendors only PostgreSQL and Oracle - * support storing Timezone data. But those two don't save the actual timezone - * attached to a DateTime instance (for example "Europe/Berlin" or "America/Montreal") - * but the current offset of them related to UTC. That means depending on daylight saving times - * or not you may get different offsets. + * data of dates. First, of not all the supported vendors support storing Timezone data, and some of + * them only use the offset to calculate the timestamp in its default timezone (usually UTC) and persist + * the value without the offset information. They even don't save the actual timezone names attached + * to a DateTime instance (for example "Europe/Berlin" or "America/Montreal") but the current offset + * of them related to UTC. That means, depending on daylight saving times or not, you may get different + * offsets. * - * This datatype makes only sense to use, if your application works with an offset, not - * with an actual timezone that uses transitions. Otherwise your DateTime instance - * attached with a timezone such as Europe/Berlin gets saved into the database with + * This datatype makes only sense to use, if your application only needs to accept the timezone offset, + * not the actual timezone that uses transitions. Otherwise your DateTime instance + * attached with a timezone such as "Europe/Berlin" gets saved into the database with * the offset and re-created from persistence with only the offset, not the original timezone * attached. */ diff --git a/doctrine/event-manager/src/EventArgs.php b/doctrine/event-manager/src/EventArgs.php index 4795ba6be..eea3d8a0a 100644 --- a/doctrine/event-manager/src/EventArgs.php +++ b/doctrine/event-manager/src/EventArgs.php @@ -15,10 +15,8 @@ class EventArgs { /** * Single instance of EventArgs. - * - * @var EventArgs|null */ - private static $_emptyEventArgsInstance; + private static EventArgs|null $emptyEventArgsInstance = null; /** * Gets the single, empty and immutable EventArgs instance. @@ -31,15 +29,9 @@ class EventArgs * * @link https://msdn.microsoft.com/en-us/library/system.eventargs.aspx * @see EventManager::dispatchEvent - * - * @return EventArgs */ - public static function getEmptyInstance() + public static function getEmptyInstance(): EventArgs { - if (! self::$_emptyEventArgsInstance) { - self::$_emptyEventArgsInstance = new EventArgs(); - } - - return self::$_emptyEventArgsInstance; + return self::$emptyEventArgsInstance ??= new EventArgs(); } } diff --git a/doctrine/event-manager/src/EventManager.php b/doctrine/event-manager/src/EventManager.php index 6d841be27..86f5e4536 100644 --- a/doctrine/event-manager/src/EventManager.php +++ b/doctrine/event-manager/src/EventManager.php @@ -1,8 +1,8 @@ */ - private $listeners = []; + private array $listeners = []; /** * Dispatches an event to all registered listeners. @@ -28,16 +28,14 @@ class EventManager * the name of the method that is invoked on listeners. * @param EventArgs|null $eventArgs The event arguments to pass to the event handlers/listeners. * If not supplied, the single empty EventArgs instance is used. - * - * @return void */ - public function dispatchEvent($eventName, ?EventArgs $eventArgs = null) + public function dispatchEvent(string $eventName, EventArgs|null $eventArgs = null): void { if (! isset($this->listeners[$eventName])) { return; } - $eventArgs = $eventArgs ?? EventArgs::getEmptyInstance(); + $eventArgs ??= EventArgs::getEmptyInstance(); foreach ($this->listeners[$eventName] as $listener) { $listener->$eventName($eventArgs); @@ -47,24 +45,12 @@ public function dispatchEvent($eventName, ?EventArgs $eventArgs = null) /** * Gets the listeners of a specific event. * - * @param string|null $event The name of the event. + * @param string $event The name of the event. * - * @return object[]|array The event listeners for the specified event, or all event listeners. - * @psalm-return ($event is null ? array : object[]) + * @return object[] */ - public function getListeners($event = null) + public function getListeners(string $event): array { - if ($event === null) { - Deprecation::trigger( - 'doctrine/event-manager', - 'https://github.com/doctrine/event-manager/pull/50', - 'Calling %s without an event name is deprecated. Call getAllListeners() instead.', - __METHOD__ - ); - - return $this->getAllListeners(); - } - return $this->listeners[$event] ?? []; } @@ -80,12 +66,8 @@ public function getAllListeners(): array /** * Checks whether an event has any registered listeners. - * - * @param string $event - * - * @return bool TRUE if the specified event has any listeners, FALSE otherwise. */ - public function hasListeners($event) + public function hasListeners(string $event): bool { return ! empty($this->listeners[$event]); } @@ -95,10 +77,8 @@ public function hasListeners($event) * * @param string|string[] $events The event(s) to listen on. * @param object $listener The listener object. - * - * @return void */ - public function addEventListener($events, $listener) + public function addEventListener(string|array $events, object $listener): void { // Picks the hash code related to that listener $hash = spl_object_hash($listener); @@ -114,11 +94,8 @@ public function addEventListener($events, $listener) * Removes an event listener from the specified events. * * @param string|string[] $events - * @param object $listener - * - * @return void */ - public function removeEventListener($events, $listener) + public function removeEventListener(string|array $events, object $listener): void { // Picks the hash code related to that listener $hash = spl_object_hash($listener); @@ -129,27 +106,23 @@ public function removeEventListener($events, $listener) } /** - * Adds an EventSubscriber. The subscriber is asked for all the events it is - * interested in and added as a listener for these events. + * Adds an EventSubscriber. * - * @param EventSubscriber $subscriber The subscriber. - * - * @return void + * The subscriber is asked for all the events it is interested in and added + * as a listener for these events. */ - public function addEventSubscriber(EventSubscriber $subscriber) + public function addEventSubscriber(EventSubscriber $subscriber): void { $this->addEventListener($subscriber->getSubscribedEvents(), $subscriber); } /** - * Removes an EventSubscriber. The subscriber is asked for all the events it is - * interested in and removed as a listener for these events. - * - * @param EventSubscriber $subscriber The subscriber. + * Removes an EventSubscriber. * - * @return void + * The subscriber is asked for all the events it is interested in and removed + * as a listener for these events. */ - public function removeEventSubscriber(EventSubscriber $subscriber) + public function removeEventSubscriber(EventSubscriber $subscriber): void { $this->removeEventListener($subscriber->getSubscribedEvents(), $subscriber); }