diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml index 0954c369b8..896b7a7a17 100644 --- a/.github/workflows/continuous-integration.yml +++ b/.github/workflows/continuous-integration.yml @@ -36,6 +36,7 @@ jobs: - "8.1" - "8.2" - "8.3" + - "8.4" dbal-version: - "default" - "3.7" @@ -107,6 +108,7 @@ jobs: php-version: - "8.2" - "8.3" + - "8.4" dbal-version: - "default" - "3.7" @@ -180,6 +182,7 @@ jobs: php-version: - "8.2" - "8.3" + - "8.4" dbal-version: - "default" - "3.7" @@ -246,6 +249,7 @@ jobs: php-version: - "8.2" - "8.3" + - "8.4" dbal-version: - "default" - "3.7" diff --git a/UPGRADE.md b/UPGRADE.md index afb898e0d0..975c567a5b 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -733,6 +733,14 @@ Use `toIterable()` instead. # Upgrade to 2.20 +## Explictly forbid property hooks + +Property hooks are not supported yet by Doctrine ORM. Until support is added, +they are explicitly forbidden because the support would result in a breaking +change in behavior. + +Progress on this is tracked at https://github.com/doctrine/orm/issues/11624 . + ## PARTIAL DQL syntax is undeprecated for non-object hydration Use of the PARTIAL keyword is not deprecated anymore in DQL when used with a hydrator diff --git a/composer.json b/composer.json index cb9fcdbe36..1d7a00b818 100644 --- a/composer.json +++ b/composer.json @@ -15,7 +15,8 @@ "config": { "allow-plugins": { "composer/package-versions-deprecated": true, - "dealerdirect/phpcodesniffer-composer-installer": true + "dealerdirect/phpcodesniffer-composer-installer": true, + "phpstan/extension-installer": true }, "sort-packages": true }, @@ -39,7 +40,9 @@ "doctrine/coding-standard": "^12.0", "phpbench/phpbench": "^1.0", "phpdocumentor/guides-cli": "^1.4", + "phpstan/extension-installer": "^1.4", "phpstan/phpstan": "1.12.6", + "phpstan/phpstan-deprecation-rules": "^1.2", "phpunit/phpunit": "^10.4.0", "psr/log": "^1 || ^2 || ^3", "squizlabs/php_codesniffer": "3.7.2", diff --git a/docs/en/reference/metadata-drivers.rst b/docs/en/reference/metadata-drivers.rst index 1b4faadb3c..6c3d62d859 100644 --- a/docs/en/reference/metadata-drivers.rst +++ b/docs/en/reference/metadata-drivers.rst @@ -70,8 +70,8 @@ implements the ``MappingDriver`` interface: /** * Loads the metadata for the specified class into the provided container. * - * @psalm-param class-string $className - * @psalm-param ClassMetadata $metadata + * @param class-string $className + * @param ClassMetadata $metadata * * @return void * @@ -82,8 +82,7 @@ implements the ``MappingDriver`` interface: /** * Gets the names of all mapped classes known to this driver. * - * @return array The names of all mapped classes known to this driver. - * @psalm-return list + * @return list The names of all mapped classes known to this driver. */ public function getAllClassNames(); @@ -91,7 +90,7 @@ implements the ``MappingDriver`` interface: * Returns whether the class with the specified name should have its metadata loaded. * This is only the case if it is either mapped as an Entity or a MappedSuperclass. * - * @psalm-param class-string $className + * @param class-string $className * * @return bool */ diff --git a/phpstan-dbal3.neon b/phpstan-dbal3.neon index b9ef942c96..724fe2003f 100644 --- a/phpstan-dbal3.neon +++ b/phpstan-dbal3.neon @@ -27,3 +27,10 @@ parameters: message: '#Negated boolean expression is always false\.#' paths: - src/Mapping/Driver/AttributeDriver.php + + - + message: '~^Call to deprecated method getEventManager\(\) of class Doctrine\\DBAL\\Connection\.$~' + path: src/EntityManager.php + - + message: '~deprecated class Doctrine\\DBAL\\Tools\\Console\\Command\\ReservedWordsCommand\:~' + path: src/Tools/Console/ConsoleRunner.php diff --git a/src/Mapping/ClassMetadata.php b/src/Mapping/ClassMetadata.php index f58e00e72f..70d3ea7042 100644 --- a/src/Mapping/ClassMetadata.php +++ b/src/Mapping/ClassMetadata.php @@ -1039,6 +1039,7 @@ public function isNullable(string $fieldName): bool */ public function getColumnName(string $fieldName): string { + // @phpstan-ignore property.deprecated return $this->columnNames[$fieldName] ?? $fieldName; } @@ -1188,6 +1189,7 @@ protected function validateAndCompleteFieldMapping(array $mapping): FieldMapping $mapping->quoted = true; } + // @phpstan-ignore property.deprecated $this->columnNames[$mapping->fieldName] = $mapping->columnName; if (isset($this->fieldNames[$mapping->columnName]) || ($this->discriminatorColumn && $this->discriminatorColumn->name === $mapping->columnName)) { @@ -1768,6 +1770,7 @@ public function setAttributeOverride(string $fieldName, array $overrideMapping): unset($this->fieldMappings[$fieldName]); unset($this->fieldNames[$mapping->columnName]); + // @phpstan-ignore property.deprecated unset($this->columnNames[$mapping->fieldName]); $overrideMapping = $this->validateAndCompleteFieldMapping($overrideMapping); @@ -1918,8 +1921,9 @@ public function addInheritedAssociationMapping(AssociationMapping $mapping/*, $o public function addInheritedFieldMapping(FieldMapping $fieldMapping): void { $this->fieldMappings[$fieldMapping->fieldName] = $fieldMapping; - $this->columnNames[$fieldMapping->fieldName] = $fieldMapping->columnName; - $this->fieldNames[$fieldMapping->columnName] = $fieldMapping->fieldName; + // @phpstan-ignore property.deprecated + $this->columnNames[$fieldMapping->fieldName] = $fieldMapping->columnName; + $this->fieldNames[$fieldMapping->columnName] = $fieldMapping->fieldName; if (isset($fieldMapping->generated)) { $this->requiresFetchAfterChange = true; diff --git a/src/Mapping/Driver/XmlDriver.php b/src/Mapping/Driver/XmlDriver.php index ff473ce356..49f2d34d94 100644 --- a/src/Mapping/Driver/XmlDriver.php +++ b/src/Mapping/Driver/XmlDriver.php @@ -411,6 +411,7 @@ public function loadMetadataForClass($className, PersistenceClassMetadata $metad /** @psalm-suppress DeprecatedConstant */ $orderBy[(string) $orderByField['name']] = isset($orderByField['direction']) ? (string) $orderByField['direction'] + // @phpstan-ignore classConstant.deprecated : (enum_exists(Order::class) ? Order::Ascending->value : Criteria::ASC); } @@ -540,6 +541,7 @@ public function loadMetadataForClass($className, PersistenceClassMetadata $metad /** @psalm-suppress DeprecatedConstant */ $orderBy[(string) $orderByField['name']] = isset($orderByField['direction']) ? (string) $orderByField['direction'] + // @phpstan-ignore classConstant.deprecated : (enum_exists(Order::class) ? Order::Ascending->value : Criteria::ASC); } diff --git a/src/QueryBuilder.php b/src/QueryBuilder.php index fe2d750e33..3bb60a2bcc 100644 --- a/src/QueryBuilder.php +++ b/src/QueryBuilder.php @@ -301,6 +301,7 @@ private function findRootAlias(string $alias, string $parentAlias): string } else { // Should never happen with correct joining order. Might be // thoughtful to throw exception instead. + // @phpstan-ignore method.deprecated $rootAlias = $this->getRootAlias(); } @@ -583,6 +584,7 @@ public function add(string $dqlPartName, string|object|array $dqlPart, bool $app $newDqlPart = []; foreach ($dqlPart as $k => $v) { + // @phpstan-ignore method.deprecated $k = is_numeric($k) ? $this->getRootAlias() : $k; $newDqlPart[$k] = $v; diff --git a/tests/Tests/TestInit.php b/tests/Tests/TestInit.php index eb2db60674..5b8ec4048f 100644 --- a/tests/Tests/TestInit.php +++ b/tests/Tests/TestInit.php @@ -16,9 +16,8 @@ use function mkdir; use const E_ALL; -use const E_STRICT; -error_reporting(E_ALL | E_STRICT); +error_reporting(E_ALL); date_default_timezone_set('UTC'); if (file_exists(__DIR__ . '/../../vendor/autoload.php')) {