Skip to content

Commit c5ef72d

Browse files
committed
Merge branch '3.1.x' into 4.0.x
* 3.1.x: Backport QueryParameterTest (#11288) Test different ways of settings query parameters Be less restrictive in DiscriminatorColumnMapping phpdoc (#11226) Allow (Array)ParameterType in QueryBuilder Do not implicitly cast glob's return type Do not cast file_put_contents's return type Do not implicitly cast getLockTime()'s return type Do not implicitly cast getLockContent()'s return value
2 parents cbab4d6 + 2df4d75 commit c5ef72d

File tree

5 files changed

+146
-27
lines changed

5 files changed

+146
-27
lines changed

src/Cache/Region/FileLockRegion.php

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ private function isLocked(CacheKey $key, Lock|null $lock = null): bool
6767
$time = $this->getLockTime($filename);
6868
$content = $this->getLockContent($filename);
6969

70-
if (! $content || ! $time) {
70+
if ($content === false || $time === false) {
7171
@unlink($filename);
7272

7373
return false;
@@ -156,12 +156,10 @@ public function evictAll(): bool
156156
{
157157
// The check below is necessary because on some platforms glob returns false
158158
// when nothing matched (even though no errors occurred)
159-
$filenames = glob(sprintf('%s/*.%s', $this->directory, self::LOCK_EXTENSION));
159+
$filenames = glob(sprintf('%s/*.%s', $this->directory, self::LOCK_EXTENSION)) ?: [];
160160

161-
if ($filenames) {
162-
foreach ($filenames as $filename) {
163-
@unlink($filename);
164-
}
161+
foreach ($filenames as $filename) {
162+
@unlink($filename);
165163
}
166164

167165
return $this->region->evictAll();
@@ -176,7 +174,7 @@ public function lock(CacheKey $key): Lock|null
176174
$lock = Lock::createLockRead();
177175
$filename = $this->getLockFileName($key);
178176

179-
if (! @file_put_contents($filename, $lock->value, LOCK_EX)) {
177+
if (@file_put_contents($filename, $lock->value, LOCK_EX) === false) {
180178
return null;
181179
}
182180

src/Mapping/ClassMetadata.php

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2108,13 +2108,12 @@ public function addEntityListener(string $eventName, string $class, string $meth
21082108
* @param DiscriminatorColumnMapping|mixed[]|null $columnDef
21092109
* @psalm-param DiscriminatorColumnMapping|array{
21102110
* name: string|null,
2111-
* fieldName?: string,
2112-
* type?: string,
2113-
* length?: int,
2111+
* fieldName?: string|null,
2112+
* type?: string|null,
2113+
* length?: int|null,
21142114
* columnDefinition?: string|null,
21152115
* enumType?: class-string<BackedEnum>|null,
2116-
* options?:array<string,
2117-
* mixed>|null
2116+
* options?: array<string, mixed>|null
21182117
* }|null $columnDef
21192118
*
21202119
* @throws MappingException
@@ -2136,13 +2135,9 @@ public function setDiscriminatorColumn(DiscriminatorColumnMapping|array|null $co
21362135
throw MappingException::duplicateColumnName($this->name, $columnDef['name']);
21372136
}
21382137

2139-
if (! isset($columnDef['fieldName'])) {
2140-
$columnDef['fieldName'] = $columnDef['name'];
2141-
}
2142-
2143-
if (! isset($columnDef['type'])) {
2144-
$columnDef['type'] = 'string';
2145-
}
2138+
$columnDef['fieldName'] ??= $columnDef['name'];
2139+
$columnDef['type'] ??= 'string';
2140+
$columnDef['options'] ??= [];
21462141

21472142
if (in_array($columnDef['type'], ['boolean', 'array', 'object', 'datetime', 'time', 'date'], true)) {
21482143
throw MappingException::invalidDiscriminatorColumnType($this->name, $columnDef['type']);

src/Mapping/DiscriminatorColumnMapping.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,10 @@ public function __construct(
3535
* type: string,
3636
* fieldName: string,
3737
* name: string,
38-
* length?: int,
39-
* columnDefinition?: string,
40-
* enumType?: class-string<BackedEnum>,
41-
* options?: array<string, mixed>,
38+
* length?: int|null,
39+
* columnDefinition?: string|null,
40+
* enumType?: class-string<BackedEnum>|null,
41+
* options?: array<string, mixed>|null,
4242
* } $mappingArray
4343
*/
4444
public static function fromMappingArray(array $mappingArray): self
@@ -54,7 +54,7 @@ public static function fromMappingArray(array $mappingArray): self
5454
}
5555

5656
if (property_exists($mapping, $key)) {
57-
$mapping->$key = $value;
57+
$mapping->$key = $value ?? $mapping->$key;
5858
} else {
5959
throw new Exception('Unknown property ' . $key . ' on class ' . static::class);
6060
}

src/QueryBuilder.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66

77
use Doctrine\Common\Collections\ArrayCollection;
88
use Doctrine\Common\Collections\Criteria;
9+
use Doctrine\DBAL\ArrayParameterType;
10+
use Doctrine\DBAL\ParameterType;
911
use Doctrine\ORM\Internal\NoUnknownNamedArguments;
1012
use Doctrine\ORM\Internal\QueryType;
1113
use Doctrine\ORM\Query\Expr;
@@ -431,12 +433,12 @@ public function getRootEntities(): array
431433
* ->setParameter('user_id', 1);
432434
* </code>
433435
*
434-
* @param string|int $key The parameter position or name.
435-
* @param string|int|null $type ParameterType::* or \Doctrine\DBAL\Types\Type::* constant
436+
* @param string|int $key The parameter position or name.
437+
* @param ParameterType|ArrayParameterType|string|int|null $type ParameterType::*, ArrayParameterType::* or \Doctrine\DBAL\Types\Type::* constant
436438
*
437439
* @return $this
438440
*/
439-
public function setParameter(string|int $key, mixed $value, string|int|null $type = null): static
441+
public function setParameter(string|int $key, mixed $value, ParameterType|ArrayParameterType|string|int|null $type = null): static
440442
{
441443
$existingParameter = $this->getParameter($key);
442444

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Doctrine\Tests\ORM\Functional;
6+
7+
use Doctrine\DBAL\ArrayParameterType;
8+
use Doctrine\DBAL\ParameterType;
9+
use Doctrine\DBAL\Types\Types;
10+
use Doctrine\Tests\Models\CMS\CmsUser;
11+
use Doctrine\Tests\OrmFunctionalTestCase;
12+
use PHPUnit\Framework\Attributes\Group;
13+
14+
#[Group('GH-11278')]
15+
final class QueryParameterTest extends OrmFunctionalTestCase
16+
{
17+
private int $userId;
18+
19+
protected function setUp(): void
20+
{
21+
$this->useModelSet('cms');
22+
23+
parent::setUp();
24+
25+
$user = new CmsUser();
26+
$user->name = 'John Doe';
27+
$user->username = 'john';
28+
$user2 = new CmsUser();
29+
$user2->name = 'Jane Doe';
30+
$user2->username = 'jane';
31+
$user3 = new CmsUser();
32+
$user3->name = 'Just Bill';
33+
$user3->username = 'bill';
34+
35+
$this->_em->persist($user);
36+
$this->_em->persist($user2);
37+
$this->_em->persist($user3);
38+
$this->_em->flush();
39+
40+
$this->userId = $user->id;
41+
42+
$this->_em->clear();
43+
}
44+
45+
public function testParameterTypeInBuilder(): void
46+
{
47+
$result = $this->_em->createQueryBuilder()
48+
->from(CmsUser::class, 'u')
49+
->select('u.name')
50+
->where('u.id = :id')
51+
->setParameter('id', $this->userId, ParameterType::INTEGER)
52+
->getQuery()
53+
->getArrayResult();
54+
55+
self::assertSame([['name' => 'John Doe']], $result);
56+
}
57+
58+
public function testParameterTypeInQuery(): void
59+
{
60+
$result = $this->_em->createQueryBuilder()
61+
->from(CmsUser::class, 'u')
62+
->select('u.name')
63+
->where('u.id = :id')
64+
->getQuery()
65+
->setParameter('id', $this->userId, ParameterType::INTEGER)
66+
->getArrayResult();
67+
68+
self::assertSame([['name' => 'John Doe']], $result);
69+
}
70+
71+
public function testDbalTypeStringInBuilder(): void
72+
{
73+
$result = $this->_em->createQueryBuilder()
74+
->from(CmsUser::class, 'u')
75+
->select('u.name')
76+
->where('u.id = :id')
77+
->setParameter('id', $this->userId, Types::INTEGER)
78+
->getQuery()
79+
->getArrayResult();
80+
81+
self::assertSame([['name' => 'John Doe']], $result);
82+
}
83+
84+
public function testDbalTypeStringInQuery(): void
85+
{
86+
$result = $this->_em->createQueryBuilder()
87+
->from(CmsUser::class, 'u')
88+
->select('u.name')
89+
->where('u.id = :id')
90+
->getQuery()
91+
->setParameter('id', $this->userId, Types::INTEGER)
92+
->getArrayResult();
93+
94+
self::assertSame([['name' => 'John Doe']], $result);
95+
}
96+
97+
public function testArrayParameterTypeInBuilder(): void
98+
{
99+
$result = $this->_em->createQueryBuilder()
100+
->from(CmsUser::class, 'u')
101+
->select('u.name')
102+
->where('u.username IN (:usernames)')
103+
->orderBy('u.username')
104+
->setParameter('usernames', ['john', 'jane'], ArrayParameterType::STRING)
105+
->getQuery()
106+
->getArrayResult();
107+
108+
self::assertSame([['name' => 'Jane Doe'], ['name' => 'John Doe']], $result);
109+
}
110+
111+
public function testArrayParameterTypeInQuery(): void
112+
{
113+
$result = $this->_em->createQueryBuilder()
114+
->from(CmsUser::class, 'u')
115+
->select('u.name')
116+
->where('u.username IN (:usernames)')
117+
->orderBy('u.username')
118+
->getQuery()
119+
->setParameter('usernames', ['john', 'jane'], ArrayParameterType::STRING)
120+
->getArrayResult();
121+
122+
self::assertSame([['name' => 'Jane Doe'], ['name' => 'John Doe']], $result);
123+
}
124+
}

0 commit comments

Comments
 (0)