diff --git a/UPGRADE.md b/UPGRADE.md index b24f210b0e3..f81bf7d449b 100644 --- a/UPGRADE.md +++ b/UPGRADE.md @@ -515,6 +515,11 @@ Use `toIterable()` instead. # Upgrade to 2.14 +## Deprecated constructing a `CacheKey` without `$hash` + +The `Doctrine\ORM\Cache\CacheKey` class has an explicit constructor now with +an optional parameter `$hash`. That parameter will become mandatory in 3.0. + ## Deprecated `AttributeDriver::$entityAnnotationClasses` If you need to change the behavior of `AttributeDriver::isTransient()`, diff --git a/composer.json b/composer.json index 4e031f3de36..4e282cf4c2d 100644 --- a/composer.json +++ b/composer.json @@ -38,12 +38,12 @@ "require-dev": { "doctrine/coding-standard": "^10.0", "phpbench/phpbench": "^1.0", - "phpstan/phpstan": "1.9.0", + "phpstan/phpstan": "1.9.2", "phpunit/phpunit": "^9.5", "psr/log": "^1 || ^2 || ^3", "squizlabs/php_codesniffer": "3.7.1", "symfony/cache": "^4.4 || ^5.4 || ^6.0", - "vimeo/psalm": "4.29.0" + "vimeo/psalm": "4.30.0" }, "suggest": { "ext-dom": "Provides support for XSD validation for XML mapping files", diff --git a/lib/Doctrine/ORM/Query/Expr/Base.php b/lib/Doctrine/ORM/Query/Expr/Base.php index bdab1c9ea7e..6fe3e347d5a 100644 --- a/lib/Doctrine/ORM/Query/Expr/Base.php +++ b/lib/Doctrine/ORM/Query/Expr/Base.php @@ -5,6 +5,7 @@ namespace Doctrine\ORM\Query\Expr; use InvalidArgumentException; +use Stringable; use function count; use function get_class; @@ -30,10 +31,10 @@ abstract class Base /** @var string */ protected $postSeparator = ')'; - /** @psalm-var list */ + /** @var list */ protected $allowedClasses = []; - /** @psalm-var list */ + /** @var list */ protected $parts = []; /** @param mixed $args */ diff --git a/lib/Doctrine/ORM/Query/Expr/Join.php b/lib/Doctrine/ORM/Query/Expr/Join.php index 588826b048c..906af5640d4 100644 --- a/lib/Doctrine/ORM/Query/Expr/Join.php +++ b/lib/Doctrine/ORM/Query/Expr/Join.php @@ -28,7 +28,7 @@ public function __construct( protected string $join, protected string|null $alias = null, protected string|null $conditionType = null, - protected string|Comparison|Composite|null $condition = null, + protected string|Comparison|Composite|Func|null $condition = null, protected string|null $indexBy = null, ) { } @@ -55,7 +55,7 @@ public function getConditionType(): string|null return $this->conditionType; } - public function getCondition(): string|Comparison|Composite|null + public function getCondition(): string|Comparison|Composite|Func|null { return $this->condition; } diff --git a/lib/Doctrine/ORM/QueryBuilder.php b/lib/Doctrine/ORM/QueryBuilder.php index 40abef2a065..69c92e1956f 100644 --- a/lib/Doctrine/ORM/QueryBuilder.php +++ b/lib/Doctrine/ORM/QueryBuilder.php @@ -818,7 +818,7 @@ public function join( string $join, string $alias, string|null $conditionType = null, - string|Expr\Composite|Expr\Comparison|null $condition = null, + string|Expr\Composite|Expr\Comparison|Expr\Func|null $condition = null, string|null $indexBy = null, ): static { return $this->innerJoin($join, $alias, $conditionType, $condition, $indexBy); @@ -845,7 +845,7 @@ public function innerJoin( string $join, string $alias, string|null $conditionType = null, - string|Expr\Composite|Expr\Comparison|null $condition = null, + string|Expr\Composite|Expr\Comparison|Expr\Func|null $condition = null, string|null $indexBy = null, ): static { $parentAlias = substr($join, 0, (int) strpos($join, '.')); @@ -886,7 +886,7 @@ public function leftJoin( string $join, string $alias, string|null $conditionType = null, - string|Expr\Composite|Expr\Comparison|null $condition = null, + string|Expr\Composite|Expr\Comparison|Expr\Func|null $condition = null, string|null $indexBy = null, ): static { $parentAlias = substr($join, 0, (int) strpos($join, '.')); diff --git a/lib/Doctrine/ORM/Tools/SchemaTool.php b/lib/Doctrine/ORM/Tools/SchemaTool.php index 747654ce609..2733dc0e97d 100644 --- a/lib/Doctrine/ORM/Tools/SchemaTool.php +++ b/lib/Doctrine/ORM/Tools/SchemaTool.php @@ -92,7 +92,7 @@ public function createSchema(array $classes): void * * @psalm-param list $classes * - * @return string[] The SQL statements needed to create the schema for the classes. + * @return list The SQL statements needed to create the schema for the classes. */ public function getCreateSchemaSql(array $classes): array { @@ -122,7 +122,7 @@ private function processingNotRequired( * * @param mixed[] $indexData index or unique constraint data * - * @return string[] Column names from combined fields and columns mappings + * @return list Column names from combined fields and columns mappings */ private function getIndexColumns(ClassMetadata $class, array $indexData): array { @@ -832,7 +832,7 @@ public function dropDatabase(): void /** * Gets the SQL needed to drop the database schema for the connections database. * - * @return string[] + * @return list */ public function getDropDatabaseSQL(): array { @@ -846,7 +846,7 @@ public function getDropDatabaseSQL(): array * * @psalm-param list $classes * - * @return string[] + * @return list */ public function getDropSchemaSQL(array $classes): array { @@ -917,11 +917,11 @@ public function updateSchema(array $classes, bool $saveMode = false): void * Gets the sequence of SQL statements that need to be performed in order * to bring the given class mappings in-synch with the relational schema. * - * @param mixed[] $classes The classes to consider. - * @param bool $saveMode If TRUE, only generates SQL for a partial update - * that does not include SQL for dropping assets which are scheduled for deletion. + * @param bool $saveMode If TRUE, only generates SQL for a partial update + * that does not include SQL for dropping assets which are scheduled for deletion. + * @param list $classes The classes to consider. * - * @return string[] The sequence of SQL statements. + * @return list The sequence of SQL statements. */ public function getUpdateSchemaSql(array $classes, bool $saveMode = false): array { diff --git a/psalm-baseline.xml b/psalm-baseline.xml index ad2f5c49ab0..36e57623007 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1,5 +1,5 @@ - + ! $filteredParameters->isEmpty() ? $filteredParameters->first() : null @@ -1323,18 +1323,9 @@ $parts - - - $this->parts - - - $this->parts[0] - - - + $part - $this->parts[0] diff --git a/tests/Doctrine/Tests/ORM/Cache/CacheKeyTest.php b/tests/Doctrine/Tests/ORM/Cache/CacheKeyTest.php index 4ed0cf68071..530f2a9d2e8 100644 --- a/tests/Doctrine/Tests/ORM/Cache/CacheKeyTest.php +++ b/tests/Doctrine/Tests/ORM/Cache/CacheKeyTest.php @@ -4,6 +4,7 @@ namespace Doctrine\Tests\ORM\Cache; +use Doctrine\ORM\Cache\CacheKey; use Doctrine\ORM\Cache\CollectionCacheKey; use Doctrine\ORM\Cache\EntityCacheKey; use Doctrine\Tests\DoctrineTestCase; @@ -66,4 +67,12 @@ public function testCollectionCacheKeyAssociationCollision(): void self::assertNotEquals($key1->hash, $key2->hash); } + + public function testConstructor(): void + { + $key = new class ('my-hash') extends CacheKey { + }; + + self::assertSame('my-hash', $key->hash); + } } diff --git a/tests/Doctrine/Tests/ORM/QueryBuilderTest.php b/tests/Doctrine/Tests/ORM/QueryBuilderTest.php index 727d8f0b7fa..c1c5bd4eecd 100644 --- a/tests/Doctrine/Tests/ORM/QueryBuilderTest.php +++ b/tests/Doctrine/Tests/ORM/QueryBuilderTest.php @@ -169,6 +169,23 @@ public function testComplexInnerJoinWithCompositeCondition(): void ); } + public function testComplexInnerJoinWithFuncCondition(): void + { + $qb = $this->entityManager->createQueryBuilder(); + $qb + ->select('u', 'a') + ->from(CmsUser::class, 'u') + ->innerJoin('u.articles', 'a', Join::WITH, $qb->expr()->in( + 'u.id', + [1, 2, 3], + )); + + $this->assertValidQueryBuilder( + $qb, + 'SELECT u, a FROM Doctrine\Tests\Models\CMS\CmsUser u INNER JOIN u.articles a WITH u.id IN(1, 2, 3)', + ); + } + public function testComplexInnerJoinWithIndexBy(): void { $qb = $this->entityManager->createQueryBuilder()