Skip to content

Commit 0871900

Browse files
committed
Merge remote-tracking branch 'origin/1.3.x' into 1.4.x
2 parents cf8f114 + f42828a commit 0871900

8 files changed

+170
-0
lines changed

extension.neon

+6
Original file line numberDiff line numberDiff line change
@@ -426,3 +426,9 @@ services:
426426
class: PHPStan\Type\Doctrine\EntityManagerInterfaceThrowTypeExtension
427427
tags:
428428
- phpstan.dynamicMethodThrowTypeExtension
429+
430+
# Forbidden class names extension
431+
-
432+
class: PHPStan\Classes\DoctrineProxyForbiddenClassNamesExtension
433+
tags:
434+
- phpstan.forbiddenClassNamesExtension

phpstan-baseline.neon

+5
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,11 @@ parameters:
2525
count: 1
2626
path: src/Stubs/Doctrine/StubFilesExtensionLoader.php
2727

28+
-
29+
message: "#^Accessing PHPStan\\\\Rules\\\\Classes\\\\InstantiationRule\\:\\:class is not covered by backward compatibility promise\\. The class might change in a minor PHPStan version\\.$#"
30+
count: 1
31+
path: tests/Classes/DoctrineProxyForbiddenClassNamesExtensionTest.php
32+
2833
-
2934
message: "#^Accessing PHPStan\\\\Rules\\\\DeadCode\\\\UnusedPrivatePropertyRule\\:\\:class is not covered by backward compatibility promise\\. The class might change in a minor PHPStan version\\.$#"
3035
count: 1

rules.neon

+4
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,7 @@ services:
5959
- phpstan.rules.rule
6060
-
6161
class: PHPStan\Rules\Doctrine\ORM\EntityConstructorNotFinalRule
62+
-
63+
class: PHPStan\Classes\DoctrineProxyForbiddenClassNamesExtension
64+
tags:
65+
- phpstan.forbiddenClassNamesExtension
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Classes;
4+
5+
use Doctrine\Persistence\Proxy;
6+
use PHPStan\Type\Doctrine\ObjectMetadataResolver;
7+
8+
class DoctrineProxyForbiddenClassNamesExtension implements ForbiddenClassNameExtension
9+
{
10+
11+
/** @var ObjectMetadataResolver */
12+
private $objectMetadataResolver;
13+
14+
public function __construct(ObjectMetadataResolver $objectMetadataResolver)
15+
{
16+
$this->objectMetadataResolver = $objectMetadataResolver;
17+
}
18+
19+
public function getClassPrefixes(): array
20+
{
21+
$objectManager = $this->objectMetadataResolver->getObjectManager();
22+
if ($objectManager === null) {
23+
return [];
24+
}
25+
26+
$entityManagerInterface = 'Doctrine\ORM\EntityManagerInterface';
27+
28+
if (!$objectManager instanceof $entityManagerInterface) {
29+
return [];
30+
}
31+
32+
return [
33+
'Doctrine' => $objectManager->getConfiguration()->getProxyNamespace() . '\\' . Proxy::MARKER,
34+
];
35+
}
36+
37+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PHPStan\Classes;
4+
5+
use PHPStan\Rules\Classes\InstantiationRule;
6+
use PHPStan\Rules\Rule;
7+
use PHPStan\Testing\RuleTestCase;
8+
use function array_merge;
9+
10+
/**
11+
* @extends RuleTestCase<InstantiationRule>
12+
*/
13+
class DoctrineProxyForbiddenClassNamesExtensionTest extends RuleTestCase
14+
{
15+
16+
protected function getRule(): Rule
17+
{
18+
return self::getContainer()->getByType(InstantiationRule::class);
19+
}
20+
21+
public function testForbiddenClassNameExtension(): void
22+
{
23+
$this->analyse(
24+
[__DIR__ . '/data/forbidden-class-name.php'],
25+
[
26+
[
27+
'Referencing prefixed Doctrine class: App\GeneratedProxy\__CG__\App\TestDoctrineEntity.',
28+
19,
29+
'This is most likely unintentional. Did you mean to type \App\TestDoctrineEntity?',
30+
],
31+
[
32+
'Referencing prefixed PHPStan class: _PHPStan_15755dag8c\TestPhpStanEntity.',
33+
20,
34+
'This is most likely unintentional. Did you mean to type \TestPhpStanEntity?',
35+
],
36+
]
37+
);
38+
}
39+
40+
public static function getAdditionalConfigFiles(): array
41+
{
42+
return array_merge(parent::getAdditionalConfigFiles(), [
43+
__DIR__ . '/phpstan.neon',
44+
]);
45+
}
46+
47+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace App\GeneratedProxy\__CG__\App;
4+
5+
class TestDoctrineEntity
6+
{
7+
}
8+
9+
namespace _PHPStan_15755dag8c;
10+
11+
class TestPhpStanEntity
12+
{
13+
}
14+
15+
namespace ForbiddenNameClassExtension;
16+
17+
use App\GeneratedProxy\__CG__\App\TestEntity;
18+
19+
$doctrineEntity = new \App\GeneratedProxy\__CG__\App\TestDoctrineEntity();
20+
$phpStanEntity = new \_PHPStan_15755dag8c\TestPhpStanEntity();

tests/Classes/entity-manager.php

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
<?php declare(strict_types = 1);
2+
3+
use Cache\Adapter\PHPArray\ArrayCachePool;
4+
use Doctrine\Common\Annotations\AnnotationReader;
5+
use Doctrine\DBAL\DriverManager;
6+
use Doctrine\DBAL\Types\DateTimeImmutableType;
7+
use Doctrine\DBAL\Types\Type;
8+
use Doctrine\ORM\Configuration;
9+
use Doctrine\ORM\EntityManager;
10+
use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
11+
use Doctrine\ORM\Mapping\Driver\AttributeDriver;
12+
use Doctrine\Persistence\Mapping\Driver\MappingDriverChain;
13+
14+
$config = new Configuration();
15+
$config->setProxyDir(__DIR__);
16+
$config->setProxyNamespace('App\GeneratedProxy');
17+
$config->setMetadataCache(new ArrayCachePool());
18+
19+
$metadataDriver = new MappingDriverChain();
20+
$metadataDriver->addDriver(new AnnotationDriver(
21+
new AnnotationReader(),
22+
[__DIR__ . '/data']
23+
), 'PHPStan\\Rules\\Doctrine\\ORM\\');
24+
25+
if (PHP_VERSION_ID >= 80100) {
26+
$metadataDriver->addDriver(
27+
new AttributeDriver([__DIR__ . '/data-attributes']),
28+
'PHPStan\\Rules\\Doctrine\\ORMAttributes\\'
29+
);
30+
}
31+
32+
$config->setMetadataDriverImpl($metadataDriver);
33+
34+
Type::overrideType(
35+
'date',
36+
DateTimeImmutableType::class
37+
);
38+
39+
return new EntityManager(
40+
DriverManager::getConnection([
41+
'driver' => 'pdo_sqlite',
42+
'memory' => true,
43+
]),
44+
$config
45+
);

tests/Classes/phpstan.neon

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
includes:
2+
- ../../extension.neon
3+
4+
parameters:
5+
doctrine:
6+
objectManagerLoader: entity-manager.php

0 commit comments

Comments
 (0)