File tree Expand file tree Collapse file tree 11 files changed +249
-9
lines changed
tests/DoctrineIntegration Expand file tree Collapse file tree 11 files changed +249
-9
lines changed Original file line number Diff line number Diff line change 1
1
parameters :
2
2
doctrine :
3
- repositoryClass : Doctrine\ORM\EntityRepository
3
+ objectManagerLoader : ~
4
4
5
5
services :
6
6
-
@@ -17,8 +17,6 @@ services:
17
17
- phpstan.broker.dynamicMethodReturnTypeExtension
18
18
-
19
19
class : PHPStan\Type\Doctrine\ObjectManagerGetRepositoryDynamicReturnTypeExtension
20
- arguments :
21
- repositoryClass : %doctrine.repositoryClass%
22
20
tags :
23
21
- phpstan.broker.dynamicMethodReturnTypeExtension
24
22
-
@@ -29,3 +27,7 @@ services:
29
27
class : PHPStan\Type\Doctrine\ObjectRepositoryDynamicReturnTypeExtension
30
28
tags :
31
29
- phpstan.broker.dynamicMethodReturnTypeExtension
30
+ -
31
+ class : PHPStan\Type\Doctrine\ObjectMetadataResolver
32
+ arguments :
33
+ objectManagerLoader : %doctrine.objectManagerLoader%
Original file line number Diff line number Diff line change 13
13
class ObjectManagerGetRepositoryDynamicReturnTypeExtension implements \PHPStan \Type \DynamicMethodReturnTypeExtension
14
14
{
15
15
16
- /** @var string */
17
- private $ repositoryClass ;
16
+ /** @var ObjectMetadataResolver */
17
+ private $ metadataResolver ;
18
18
19
- public function __construct (string $ repositoryClass )
19
+ public function __construct (ObjectMetadataResolver $ metadataResolver )
20
20
{
21
- $ this ->repositoryClass = $ repositoryClass ;
21
+ $ this ->metadataResolver = $ metadataResolver ;
22
22
}
23
23
24
24
public function getClass (): string
@@ -47,7 +47,14 @@ public function getTypeFromMethodCall(
47
47
return new MixedType ();
48
48
}
49
49
50
- return new ObjectRepositoryType ($ argType ->getValue (), $ this ->repositoryClass );
50
+ $ objectName = $ argType ->getValue ();
51
+ $ repositoryClass = $ this ->metadataResolver ->getRepositoryClass ($ objectName );
52
+
53
+ if ($ repositoryClass === null ) {
54
+ return new MixedType ();
55
+ }
56
+
57
+ return new ObjectRepositoryType ($ objectName , $ repositoryClass );
51
58
}
52
59
53
60
}
Original file line number Diff line number Diff line change
1
+ <?php declare (strict_types = 1 );
2
+
3
+ namespace PHPStan \Type \Doctrine ;
4
+
5
+ use Doctrine \Common \Persistence \ObjectManager ;
6
+ use Doctrine \ODM \MongoDB \Mapping \ClassMetadata as ODMMetadata ;
7
+ use Doctrine \ORM \Mapping \ClassMetadata as ORMMetadata ;
8
+ use RuntimeException ;
9
+ use function file_exists ;
10
+ use function is_readable ;
11
+
12
+ final class ObjectMetadataResolver
13
+ {
14
+
15
+ /** @var ObjectManager */
16
+ private $ objectManager ;
17
+
18
+ public function __construct (string $ objectManagerLoader )
19
+ {
20
+ $ this ->objectManager = $ this ->getObjectManager ($ objectManagerLoader );
21
+ }
22
+
23
+ private function getObjectManager (string $ objectManagerLoader ): ObjectManager
24
+ {
25
+ if (! file_exists ($ objectManagerLoader ) && ! is_readable ($ objectManagerLoader )) {
26
+ throw new RuntimeException ('Object manager could not be loaded ' );
27
+ }
28
+
29
+ return require $ objectManagerLoader ;
30
+ }
31
+
32
+ public function getRepositoryClass (string $ className ): ?string
33
+ {
34
+ $ metatada = $ this ->objectManager ->getClassMetadata ($ className );
35
+
36
+ if ($ metatada instanceof ORMMetadata) {
37
+ return $ metatada ->customRepositoryClassName ?? 'Doctrine\ORM\EntityRepository ' ;
38
+ }
39
+
40
+ if ($ metatada instanceof ODMMetadata) {
41
+ return $ metatada ->customRepositoryClassName ?? 'Doctrine\ODM\MongoDB\DocumentRepository ' ;
42
+ }
43
+
44
+ return null ;
45
+ }
46
+
47
+ }
Original file line number Diff line number Diff line change @@ -16,6 +16,7 @@ public function dataTopics(): array
16
16
['documentManagerDynamicReturn ' ],
17
17
['documentRepositoryDynamicReturn ' ],
18
18
['documentManagerMergeReturn ' ],
19
+ ['customRepositoryUsage ' ],
19
20
];
20
21
}
21
22
Original file line number Diff line number Diff line change
1
+ <?php declare (strict_types = 1 );
2
+
3
+ namespace PHPStan \DoctrineIntegration \ODM \CustomRepositoryUsage ;
4
+
5
+ use Doctrine \ODM \MongoDB \DocumentManager ;
6
+ use Doctrine \ODM \MongoDB \DocumentRepository ;
7
+ use Doctrine \ODM \MongoDB \Mapping \Annotations \Document ;
8
+ use Doctrine \ODM \MongoDB \Mapping \Annotations \Id ;
9
+ use RuntimeException ;
10
+
11
+ class Example
12
+ {
13
+ /**
14
+ * @var MyRepository
15
+ */
16
+ private $ repository ;
17
+
18
+ public function __construct (DocumentManager $ documentManager )
19
+ {
20
+ $ this ->repository = $ documentManager ->getRepository (MyDocument::class);
21
+ }
22
+
23
+ public function get (): void
24
+ {
25
+ $ test = $ this ->repository ->get ('testing ' );
26
+ $ test ->doSomethingElse ();
27
+ }
28
+ }
29
+
30
+ /**
31
+ * @Document(repositoryClass=MyRepository::class)
32
+ */
33
+ class MyDocument
34
+ {
35
+ /**
36
+ * @Id(strategy="NONE", type="string")
37
+ *
38
+ * @var string
39
+ */
40
+ private $ id ;
41
+
42
+ public function doSomethingElse (): void
43
+ {
44
+ }
45
+ }
46
+
47
+ class MyRepository extends DocumentRepository
48
+ {
49
+ public function get (string $ id ): MyDocument
50
+ {
51
+ $ document = $ this ->find ($ id );
52
+
53
+ if ($ document === null ) {
54
+ throw new RuntimeException ('Not found... ' );
55
+ }
56
+
57
+ return $ document ;
58
+ }
59
+ }
Original file line number Diff line number Diff line change
1
+ <?php declare (strict_types = 1 );
2
+
3
+ use Doctrine \Common \Annotations \AnnotationReader ;
4
+ use Doctrine \Common \Annotations \AnnotationRegistry ;
5
+ use Doctrine \Common \Cache \ArrayCache ;
6
+ use Doctrine \ODM \MongoDB \Configuration ;
7
+ use Doctrine \ODM \MongoDB \DocumentManager ;
8
+ use Doctrine \ODM \MongoDB \Mapping \Driver \AnnotationDriver ;
9
+
10
+ AnnotationRegistry::registerUniqueLoader ('class_exists ' );
11
+
12
+ $ config = new Configuration ();
13
+ $ config ->setProxyDir (__DIR__ );
14
+ $ config ->setProxyNamespace ('PHPstan\Doctrine\OdmProxies ' );
15
+ $ config ->setMetadataCacheImpl (new ArrayCache ());
16
+ $ config ->setHydratorDir (__DIR__ );
17
+ $ config ->setHydratorNamespace ('PHPstan\Doctrine\OdmHydrators ' );
18
+
19
+ $ config ->setMetadataDriverImpl (
20
+ new AnnotationDriver (
21
+ new AnnotationReader (),
22
+ [__DIR__ . '/data ' ]
23
+ )
24
+ );
25
+
26
+ return DocumentManager::create (
27
+ null ,
28
+ $ config
29
+ );
Original file line number Diff line number Diff line change @@ -3,4 +3,4 @@ includes:
3
3
4
4
parameters :
5
5
doctrine :
6
- repositoryClass : Doctrine\ ODM\MongoDB\DocumentRepository
6
+ objectManagerLoader : tests/DoctrineIntegration/ ODM/document-manager.php
Original file line number Diff line number Diff line change @@ -16,6 +16,7 @@ public function dataTopics(): array
16
16
['entityManagerDynamicReturn ' ],
17
17
['entityRepositoryDynamicReturn ' ],
18
18
['entityManagerMergeReturn ' ],
19
+ ['customRepositoryUsage ' ],
19
20
];
20
21
}
21
22
Original file line number Diff line number Diff line change
1
+ <?php declare (strict_types = 1 );
2
+
3
+ namespace PHPStan \DoctrineIntegration \ORM \CustomRepositoryUsage ;
4
+
5
+ use Doctrine \ORM \EntityManagerInterface ;
6
+ use Doctrine \ORM \EntityRepository ;
7
+ use Doctrine \ORM \Mapping as ORM ;
8
+ use RuntimeException ;
9
+
10
+ class Example
11
+ {
12
+ /**
13
+ * @var MyRepository
14
+ */
15
+ private $ repository ;
16
+
17
+ public function __construct (EntityManagerInterface $ entityManager )
18
+ {
19
+ $ this ->repository = $ entityManager ->getRepository (MyEntity::class);
20
+ }
21
+
22
+ public function get (): void
23
+ {
24
+ $ test = $ this ->repository ->get (1 );
25
+ $ test ->doSomethingElse ();
26
+ }
27
+ }
28
+
29
+ /**
30
+ * @ORM\Entity(repositoryClass=MyRepository::class)
31
+ */
32
+ class MyEntity
33
+ {
34
+ /**
35
+ * @ORM\Id()
36
+ * @ORM\GeneratedValue()
37
+ * @ORM\Column(type="integer")
38
+ *
39
+ * @var int
40
+ */
41
+ private $ id ;
42
+
43
+ public function doSomethingElse (): void
44
+ {
45
+ }
46
+ }
47
+
48
+ class MyRepository extends EntityRepository
49
+ {
50
+ public function get (int $ id ): MyEntity
51
+ {
52
+ $ entity = $ this ->find ($ id );
53
+
54
+ if ($ entity === null ) {
55
+ throw new RuntimeException ('Not found... ' );
56
+ }
57
+
58
+ return $ entity ;
59
+ }
60
+ }
Original file line number Diff line number Diff line change
1
+ <?php declare (strict_types = 1 );
2
+
3
+ use Doctrine \Common \Annotations \AnnotationReader ;
4
+ use Doctrine \Common \Annotations \AnnotationRegistry ;
5
+ use Doctrine \Common \Cache \ArrayCache ;
6
+ use Doctrine \ORM \Configuration ;
7
+ use Doctrine \ORM \EntityManager ;
8
+ use Doctrine \ORM \Mapping \Driver \AnnotationDriver ;
9
+
10
+ AnnotationRegistry::registerUniqueLoader ('class_exists ' );
11
+
12
+ $ config = new Configuration ();
13
+ $ config ->setProxyDir (__DIR__ );
14
+ $ config ->setProxyNamespace ('PHPstan\Doctrine\OrmProxies ' );
15
+ $ config ->setMetadataCacheImpl (new ArrayCache ());
16
+
17
+ $ config ->setMetadataDriverImpl (
18
+ new AnnotationDriver (
19
+ new AnnotationReader (),
20
+ [__DIR__ . '/data ' ]
21
+ )
22
+ );
23
+
24
+ return EntityManager::create (
25
+ [
26
+ 'driver ' => 'pdo_sqlite ' ,
27
+ 'memory ' => true ,
28
+ ],
29
+ $ config
30
+ );
Original file line number Diff line number Diff line change 1
1
includes :
2
2
- ../../../extension.neon
3
+
4
+ parameters :
5
+ doctrine :
6
+ objectManagerLoader : tests/DoctrineIntegration/ORM/entity-manager.php
You can’t perform that action at this time.
0 commit comments