Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/1.3.x' into 1.4.x
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrejmirtes committed Mar 21, 2024
2 parents cf8f114 + f42828a commit 0871900
Show file tree
Hide file tree
Showing 8 changed files with 170 additions and 0 deletions.
6 changes: 6 additions & 0 deletions extension.neon
Original file line number Diff line number Diff line change
Expand Up @@ -426,3 +426,9 @@ services:
class: PHPStan\Type\Doctrine\EntityManagerInterfaceThrowTypeExtension
tags:
- phpstan.dynamicMethodThrowTypeExtension

# Forbidden class names extension
-
class: PHPStan\Classes\DoctrineProxyForbiddenClassNamesExtension
tags:
- phpstan.forbiddenClassNamesExtension
5 changes: 5 additions & 0 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ parameters:
count: 1
path: src/Stubs/Doctrine/StubFilesExtensionLoader.php

-
message: "#^Accessing PHPStan\\\\Rules\\\\Classes\\\\InstantiationRule\\:\\:class is not covered by backward compatibility promise\\. The class might change in a minor PHPStan version\\.$#"
count: 1
path: tests/Classes/DoctrineProxyForbiddenClassNamesExtensionTest.php

-
message: "#^Accessing PHPStan\\\\Rules\\\\DeadCode\\\\UnusedPrivatePropertyRule\\:\\:class is not covered by backward compatibility promise\\. The class might change in a minor PHPStan version\\.$#"
count: 1
Expand Down
4 changes: 4 additions & 0 deletions rules.neon
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,7 @@ services:
- phpstan.rules.rule
-
class: PHPStan\Rules\Doctrine\ORM\EntityConstructorNotFinalRule
-
class: PHPStan\Classes\DoctrineProxyForbiddenClassNamesExtension
tags:
- phpstan.forbiddenClassNamesExtension
37 changes: 37 additions & 0 deletions src/Classes/DoctrineProxyForbiddenClassNamesExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php declare(strict_types = 1);

namespace PHPStan\Classes;

use Doctrine\Persistence\Proxy;
use PHPStan\Type\Doctrine\ObjectMetadataResolver;

class DoctrineProxyForbiddenClassNamesExtension implements ForbiddenClassNameExtension
{

/** @var ObjectMetadataResolver */
private $objectMetadataResolver;

public function __construct(ObjectMetadataResolver $objectMetadataResolver)
{
$this->objectMetadataResolver = $objectMetadataResolver;
}

public function getClassPrefixes(): array
{
$objectManager = $this->objectMetadataResolver->getObjectManager();
if ($objectManager === null) {
return [];
}

$entityManagerInterface = 'Doctrine\ORM\EntityManagerInterface';

if (!$objectManager instanceof $entityManagerInterface) {
return [];
}

return [
'Doctrine' => $objectManager->getConfiguration()->getProxyNamespace() . '\\' . Proxy::MARKER,
];
}

}
47 changes: 47 additions & 0 deletions tests/Classes/DoctrineProxyForbiddenClassNamesExtensionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php declare(strict_types = 1);

namespace PHPStan\Classes;

use PHPStan\Rules\Classes\InstantiationRule;
use PHPStan\Rules\Rule;
use PHPStan\Testing\RuleTestCase;
use function array_merge;

/**
* @extends RuleTestCase<InstantiationRule>
*/
class DoctrineProxyForbiddenClassNamesExtensionTest extends RuleTestCase
{

protected function getRule(): Rule
{
return self::getContainer()->getByType(InstantiationRule::class);
}

public function testForbiddenClassNameExtension(): void
{
$this->analyse(
[__DIR__ . '/data/forbidden-class-name.php'],
[
[
'Referencing prefixed Doctrine class: App\GeneratedProxy\__CG__\App\TestDoctrineEntity.',
19,
'This is most likely unintentional. Did you mean to type \App\TestDoctrineEntity?',
],
[
'Referencing prefixed PHPStan class: _PHPStan_15755dag8c\TestPhpStanEntity.',
20,
'This is most likely unintentional. Did you mean to type \TestPhpStanEntity?',
],
]
);
}

public static function getAdditionalConfigFiles(): array
{
return array_merge(parent::getAdditionalConfigFiles(), [
__DIR__ . '/phpstan.neon',
]);
}

}
20 changes: 20 additions & 0 deletions tests/Classes/data/forbidden-class-name.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php declare(strict_types = 1);

namespace App\GeneratedProxy\__CG__\App;

class TestDoctrineEntity
{
}

namespace _PHPStan_15755dag8c;

class TestPhpStanEntity
{
}

namespace ForbiddenNameClassExtension;

use App\GeneratedProxy\__CG__\App\TestEntity;

$doctrineEntity = new \App\GeneratedProxy\__CG__\App\TestDoctrineEntity();
$phpStanEntity = new \_PHPStan_15755dag8c\TestPhpStanEntity();
45 changes: 45 additions & 0 deletions tests/Classes/entity-manager.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php declare(strict_types = 1);

use Cache\Adapter\PHPArray\ArrayCachePool;
use Doctrine\Common\Annotations\AnnotationReader;
use Doctrine\DBAL\DriverManager;
use Doctrine\DBAL\Types\DateTimeImmutableType;
use Doctrine\DBAL\Types\Type;
use Doctrine\ORM\Configuration;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
use Doctrine\ORM\Mapping\Driver\AttributeDriver;
use Doctrine\Persistence\Mapping\Driver\MappingDriverChain;

$config = new Configuration();
$config->setProxyDir(__DIR__);
$config->setProxyNamespace('App\GeneratedProxy');
$config->setMetadataCache(new ArrayCachePool());

$metadataDriver = new MappingDriverChain();
$metadataDriver->addDriver(new AnnotationDriver(
new AnnotationReader(),
[__DIR__ . '/data']
), 'PHPStan\\Rules\\Doctrine\\ORM\\');

if (PHP_VERSION_ID >= 80100) {
$metadataDriver->addDriver(
new AttributeDriver([__DIR__ . '/data-attributes']),
'PHPStan\\Rules\\Doctrine\\ORMAttributes\\'
);
}

$config->setMetadataDriverImpl($metadataDriver);

Type::overrideType(
'date',
DateTimeImmutableType::class
);

return new EntityManager(
DriverManager::getConnection([
'driver' => 'pdo_sqlite',
'memory' => true,
]),
$config
);
6 changes: 6 additions & 0 deletions tests/Classes/phpstan.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
includes:
- ../../extension.neon

parameters:
doctrine:
objectManagerLoader: entity-manager.php

0 comments on commit 0871900

Please sign in to comment.