Skip to content

Commit bc1c6fa

Browse files
committed
Merge remote-tracking branch 'origin/1.3.x' into 1.4.x
2 parents 3f5f724 + 69e422e commit bc1c6fa

File tree

7 files changed

+122
-32
lines changed

7 files changed

+122
-32
lines changed

.github/workflows/build.yml

+4-2
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ jobs:
3535
coverage: "none"
3636
php-version: "${{ matrix.php-version }}"
3737
ini-file: development
38+
extensions: "mongodb"
3839

3940
- name: "Validate Composer"
4041
run: "composer validate"
@@ -70,6 +71,7 @@ jobs:
7071
coverage: "none"
7172
php-version: "8.2"
7273
ini-file: development
74+
extensions: "mongodb"
7375

7476
- name: "Validate Composer"
7577
run: "composer validate"
@@ -115,6 +117,7 @@ jobs:
115117
coverage: "none"
116118
php-version: "${{ matrix.php-version }}"
117119
ini-file: development
120+
extensions: "mongodb"
118121

119122
- name: "Downgrade PHPUnit"
120123
if: matrix.php-version == '7.2' || matrix.php-version == '7.3'
@@ -155,9 +158,8 @@ jobs:
155158
with:
156159
coverage: "none"
157160
php-version: "${{ matrix.php-version }}"
158-
extensions: mbstring
161+
extensions: "mongodb"
159162
ini-file: development
160-
tools: composer:v2
161163

162164
- name: "Downgrade PHPUnit"
163165
if: matrix.php-version == '7.2' || matrix.php-version == '7.3'

composer.json

+7-11
Original file line numberDiff line numberDiff line change
@@ -18,29 +18,25 @@
1818
},
1919
"require-dev": {
2020
"composer/semver": "^3.3.2",
21-
"doctrine/annotations": "^1.11.0",
22-
"doctrine/collections": "^1.6",
21+
"doctrine/annotations": "^1.11 || ^2.0",
22+
"doctrine/collections": "^1.6 || ^2.1",
2323
"doctrine/common": "^2.7 || ^3.0",
2424
"doctrine/dbal": "^2.13.8 || ^3.3.3",
25-
"doctrine/lexer": "^1.2.1",
26-
"doctrine/mongodb-odm": "^1.3 || ^2.1",
25+
"doctrine/lexer": "^2.0 || ^3.0",
26+
"doctrine/mongodb-odm": "^1.3 || ^2.4.3",
2727
"doctrine/orm": "^2.14.0",
28-
"doctrine/persistence": "^1.3.8 || ^2.2.1",
28+
"doctrine/persistence": "^2.2.1 || ^3.2",
2929
"gedmo/doctrine-extensions": "^3.8",
3030
"nesbot/carbon": "^2.49",
3131
"nikic/php-parser": "^4.13.2",
3232
"php-parallel-lint/php-parallel-lint": "^1.2",
3333
"phpstan/phpstan-phpunit": "^1.3.13",
3434
"phpstan/phpstan-strict-rules": "^1.5.1",
3535
"phpunit/phpunit": "^9.5.10",
36-
"ramsey/uuid-doctrine": "^1.5.0",
37-
"symfony/cache": "^4.4.35"
36+
"ramsey/uuid": "^4.2",
37+
"symfony/cache": "^5.4"
3838
},
3939
"config": {
40-
"platform": {
41-
"ext-mongo": "1.12",
42-
"ext-mongodb": "1.6.16"
43-
},
4440
"sort-packages": true
4541
},
4642
"extra": {

src/Type/Doctrine/Descriptors/Ramsey/UuidTypeDescriptor.php

+7-10
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,13 @@
22

33
namespace PHPStan\Type\Doctrine\Descriptors\Ramsey;
44

5+
use PHPStan\Rules\Doctrine\ORM\FakeTestingUuidType;
56
use PHPStan\ShouldNotHappenException;
67
use PHPStan\Type\Doctrine\Descriptors\DoctrineTypeDescriptor;
78
use PHPStan\Type\ObjectType;
89
use PHPStan\Type\StringType;
910
use PHPStan\Type\Type;
1011
use PHPStan\Type\TypeCombinator;
11-
use Ramsey\Uuid\Doctrine\UuidBinaryOrderedTimeType;
12-
use Ramsey\Uuid\Doctrine\UuidBinaryType;
13-
use Ramsey\Uuid\Doctrine\UuidType;
1412
use Ramsey\Uuid\UuidInterface;
1513
use function in_array;
1614
use function sprintf;
@@ -19,15 +17,13 @@ class UuidTypeDescriptor implements DoctrineTypeDescriptor
1917
{
2018

2119
private const SUPPORTED_UUID_TYPES = [
22-
UuidType::class,
23-
UuidBinaryType::class,
24-
UuidBinaryOrderedTimeType::class,
20+
'Ramsey\Uuid\Doctrine\UuidType',
21+
'Ramsey\Uuid\Doctrine\UuidBinaryType',
22+
'Ramsey\Uuid\Doctrine\UuidBinaryOrderedTimeType',
23+
FakeTestingUuidType::class,
2524
];
2625

27-
/**
28-
* @phpstan-var class-string<\Doctrine\DBAL\Types\Type>
29-
* @var string
30-
*/
26+
/** @var string */
3127
private $uuidTypeName;
3228

3329
public function __construct(
@@ -46,6 +42,7 @@ public function __construct(
4642

4743
public function getType(): string
4844
{
45+
/** @var class-string<\Doctrine\DBAL\Types\Type> */
4946
return $this->uuidTypeName;
5047
}
5148

src/Type/Doctrine/Query/QueryResultTypeWalker.php

+7-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
use BackedEnum;
66
use Doctrine\ORM\EntityManagerInterface;
7-
use Doctrine\ORM\Mapping\ClassMetadata;
87
use Doctrine\ORM\Mapping\ClassMetadataInfo;
98
use Doctrine\ORM\Query;
109
use Doctrine\ORM\Query\AST;
@@ -35,6 +34,7 @@
3534
use PHPStan\Type\TypeTraverser;
3635
use PHPStan\Type\TypeUtils;
3736
use PHPStan\Type\UnionType;
37+
use function array_key_exists;
3838
use function array_map;
3939
use function assert;
4040
use function class_exists;
@@ -56,7 +56,7 @@
5656
*
5757
* It extends SqlkWalker because AST\Node::dispatch() accepts SqlWalker only
5858
*
59-
* @phpstan-type QueryComponent array{metadata: ClassMetadata<object>, parent: mixed, relation: ?array{orderBy: array<array-key, string>, indexBy: ?string, fieldName: string, targetEntity: string, sourceEntity: string, isOwningSide: bool, mappedBy: string, type: int}, map: mixed, nestingLevel: int, token: mixed}
59+
* @phpstan-import-type QueryComponent from Parser
6060
*/
6161
class QueryResultTypeWalker extends SqlWalker
6262
{
@@ -229,6 +229,7 @@ public function walkPathExpression($pathExpr)
229229
$fieldName = $pathExpr->field;
230230
$dqlAlias = $pathExpr->identificationVariable;
231231
$qComp = $this->queryComponents[$dqlAlias];
232+
assert(array_key_exists('metadata', $qComp));
232233
$class = $qComp['metadata'];
233234

234235
assert($fieldName !== null);
@@ -516,6 +517,7 @@ public function walkFunction($function)
516517
$dqlAlias = $function->pathExpression->identificationVariable;
517518
$assocField = $function->pathExpression->field;
518519
$queryComp = $this->queryComponents[$dqlAlias];
520+
assert(array_key_exists('metadata', $queryComp));
519521
$class = $queryComp['metadata'];
520522
$assoc = $class->associationMappings[$assocField];
521523
$assocClassName = $assoc['targetEntity'];
@@ -756,9 +758,11 @@ public function walkSelectExpression($selectExpression)
756758
if (is_string($expr)) {
757759
$dqlAlias = $expr;
758760
$queryComp = $this->queryComponents[$dqlAlias];
761+
assert(array_key_exists('metadata', $queryComp));
759762
$class = $queryComp['metadata'];
760763
$resultAlias = $selectExpression->fieldIdentificationVariable ?? $dqlAlias;
761764

765+
assert(array_key_exists('parent', $queryComp));
762766
if ($queryComp['parent'] !== null) {
763767
return '';
764768
}
@@ -785,6 +789,7 @@ public function walkSelectExpression($selectExpression)
785789

786790
$dqlAlias = $expr->identificationVariable;
787791
$qComp = $this->queryComponents[$dqlAlias];
792+
assert(array_key_exists('metadata', $qComp));
788793
$class = $qComp['metadata'];
789794

790795
[$typeName, $enumType] = $this->getTypeOfField($class, $fieldName);

tests/DoctrineIntegration/ORM/data/entityManagerMergeReturn.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,18 @@
22

33
namespace PHPStan\DoctrineIntegration\ORM\EntityManagerMergeReturn;
44

5-
use Doctrine\ORM\EntityManagerInterface;
5+
use Doctrine\ORM\EntityManager;
66
use Doctrine\ORM\Mapping as ORM;
77
use function PHPStan\Testing\assertType;
88

99
class Example
1010
{
1111
/**
12-
* @var EntityManagerInterface
12+
* @var EntityManager
1313
*/
1414
private $entityManager;
1515

16-
public function __construct(EntityManagerInterface $entityManager)
16+
public function __construct(EntityManager $entityManager)
1717
{
1818
$this->entityManager = $entityManager;
1919
}

tests/Rules/Doctrine/ORM/EntityColumnRuleTest.php

+3-4
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
use PHPStan\Type\Doctrine\Descriptors\SimpleArrayType;
2424
use PHPStan\Type\Doctrine\Descriptors\StringType;
2525
use PHPStan\Type\Doctrine\ObjectMetadataResolver;
26-
use Ramsey\Uuid\Doctrine\UuidType;
2726
use const PHP_VERSION_ID;
2827

2928
/**
@@ -46,8 +45,8 @@ protected function getRule(): Rule
4645
if (!Type::hasType(CustomNumericType::NAME)) {
4746
Type::addType(CustomNumericType::NAME, CustomNumericType::class);
4847
}
49-
if (!Type::hasType(UuidType::NAME)) {
50-
Type::addType(UuidType::NAME, UuidType::class);
48+
if (!Type::hasType(FakeTestingUuidType::NAME)) {
49+
Type::addType(FakeTestingUuidType::NAME, FakeTestingUuidType::class);
5150
}
5251
if (!Type::hasType('carbon')) {
5352
Type::addType('carbon', CarbonType::class);
@@ -70,7 +69,7 @@ protected function getRule(): Rule
7069
new IntegerType(),
7170
new StringType(),
7271
new SimpleArrayType(),
73-
new UuidTypeDescriptor(UuidType::class),
72+
new UuidTypeDescriptor(FakeTestingUuidType::class),
7473
new ReflectionDescriptor(CarbonImmutableType::class, $this->createBroker()),
7574
new ReflectionDescriptor(CarbonType::class, $this->createBroker()),
7675
new ReflectionDescriptor(CustomType::class, $this->createBroker()),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Rules\Doctrine\ORM;
4+
5+
use Doctrine\DBAL\Platforms\AbstractPlatform;
6+
use Doctrine\DBAL\Types\ConversionException;
7+
use Doctrine\DBAL\Types\GuidType;
8+
use Ramsey\Uuid\Uuid;
9+
use Ramsey\Uuid\UuidInterface;
10+
use Throwable;
11+
use function is_object;
12+
use function is_string;
13+
use function method_exists;
14+
15+
/**
16+
* From https://github.com/ramsey/uuid-doctrine/blob/fafebbe972cdaba9274c286ea8923e2de2579027/src/UuidType.php
17+
* Copyright (c) 2012-2022 Ben Ramsey <ben@benramsey.com>
18+
*/
19+
final class FakeTestingUuidType extends GuidType
20+
{
21+
22+
public const NAME = 'uuid';
23+
24+
/**
25+
* {@inheritdoc}
26+
*
27+
* @throws ConversionException
28+
*/
29+
public function convertToPHPValue($value, AbstractPlatform $platform): ?UuidInterface
30+
{
31+
if ($value instanceof UuidInterface) {
32+
return $value;
33+
}
34+
35+
if (!is_string($value) || $value === '') {
36+
return null;
37+
}
38+
39+
try {
40+
$uuid = Uuid::fromString($value);
41+
} catch (Throwable $e) {
42+
throw ConversionException::conversionFailed($value, self::NAME);
43+
}
44+
45+
return $uuid;
46+
}
47+
48+
/**
49+
* {@inheritdoc}
50+
*
51+
* @throws ConversionException
52+
*/
53+
public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string
54+
{
55+
if ($value === null || $value === '') {
56+
return null;
57+
}
58+
59+
if (
60+
$value instanceof UuidInterface
61+
|| (
62+
(is_string($value)
63+
|| (is_object($value) && method_exists($value, '__toString')))
64+
&& Uuid::isValid((string) $value)
65+
)
66+
) {
67+
return (string) $value;
68+
}
69+
70+
throw ConversionException::conversionFailed($value, self::NAME);
71+
}
72+
73+
public function getName(): string
74+
{
75+
return self::NAME;
76+
}
77+
78+
public function requiresSQLCommentHint(AbstractPlatform $platform): bool
79+
{
80+
return true;
81+
}
82+
83+
/**
84+
* @return string[]
85+
*/
86+
public function getMappedDatabaseTypes(AbstractPlatform $platform): array
87+
{
88+
return [self::NAME];
89+
}
90+
91+
}

0 commit comments

Comments
 (0)