diff --git a/composer.json b/composer.json index 6389be2ee6b..0a097292254 100644 --- a/composer.json +++ b/composer.json @@ -149,19 +149,19 @@ "composer/composer": "^1.0", "contao/easy-coding-standard": "^2.0", "contao/monorepo-tools": "dev-master", - "contao/phpstan": "^0.12", "contao/test-case": "^4.2", "doctrine/event-manager": "^1.0", "monolog/monolog": "^1.24", "phpunit/phpunit": "^8.4", - "psalm/plugin-phpunit": "^0.9", + "phpstan/phpstan-phpunit": "^0.12", + "phpstan/phpstan-symfony": "^0.12", + "psalm/plugin-phpunit": "^0.10", "psalm/plugin-symfony": "^1.0", "psr/event-dispatcher": "^1.0", "slam/phpstan-extensions": "^5.0", "symfony/browser-kit": "4.4.*", "symfony/phpunit-bridge": "4.4.*", - "vimeo/psalm": "^3.9", - "weirdan/doctrine-psalm-plugin": "^0.10" + "weirdan/doctrine-psalm-plugin": "^0.11" }, "extra": { "branch-alias": { diff --git a/core-bundle/src/Controller/AbstractController.php b/core-bundle/src/Controller/AbstractController.php index a6cbb5f5a73..2fc107257c1 100644 --- a/core-bundle/src/Controller/AbstractController.php +++ b/core-bundle/src/Controller/AbstractController.php @@ -43,7 +43,6 @@ protected function tagResponse(array $tags): void return; } - /* @phpstan-ignore-next-line */ $this->get('fos_http_cache.http.symfony_response_tagger')->addTags($tags); } diff --git a/core-bundle/src/Controller/InitializeController.php b/core-bundle/src/Controller/InitializeController.php index 835e8ec6d16..938eb6efb42 100644 --- a/core-bundle/src/Controller/InitializeController.php +++ b/core-bundle/src/Controller/InitializeController.php @@ -60,6 +60,10 @@ public function indexAction(): InitializeControllerResponse $realRequest->setSession($masterRequest->getSession()); } + if (!\defined('TL_SCRIPT')) { + \define('TL_SCRIPT', ''); + } + // Necessary to generate the correct base path foreach (['REQUEST_URI', 'SCRIPT_NAME', 'SCRIPT_FILENAME', 'PHP_SELF'] as $name) { $realRequest->server->set( diff --git a/core-bundle/src/Session/LazySessionAccess.php b/core-bundle/src/Session/LazySessionAccess.php index 07c1f03967d..bdb728ab498 100644 --- a/core-bundle/src/Session/LazySessionAccess.php +++ b/core-bundle/src/Session/LazySessionAccess.php @@ -73,6 +73,7 @@ private function startSession(): void $this->session->start(); + /* @phpstan-ignore-next-line */ if ($_SESSION instanceof self) { throw new \RuntimeException('Unable to start the native session, $_SESSION was not replaced.'); } diff --git a/core-bundle/tests/Controller/FaviconControllerTest.php b/core-bundle/tests/Controller/FaviconControllerTest.php index 8b592b9d166..f9e019fa10d 100644 --- a/core-bundle/tests/Controller/FaviconControllerTest.php +++ b/core-bundle/tests/Controller/FaviconControllerTest.php @@ -17,6 +17,7 @@ use Contao\FilesModel; use Contao\PageModel; use FOS\HttpCache\ResponseTagger; +use PHPUnit\Framework\MockObject\MockObject; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -68,10 +69,12 @@ public function testSvgFavicon(): void private function getController(string $iconPath): FaviconController { + /** @var PageModel&MockObject $pageModel */ $pageModel = $this->mockClassWithProperties(PageModel::class); $pageModel->id = 42; $pageModel->favicon = 'favicon-uuid'; + /** @var FilesModel&MockObject $faviconModel */ $faviconModel = $this->mockClassWithProperties(FilesModel::class); $faviconModel->path = $iconPath; $faviconModel->extension = substr($iconPath, -3); diff --git a/core-bundle/tests/Doctrine/Schema/DcaSchemaProviderTest.php b/core-bundle/tests/Doctrine/Schema/DcaSchemaProviderTest.php index ecb97fe545a..877b5ff4771 100644 --- a/core-bundle/tests/Doctrine/Schema/DcaSchemaProviderTest.php +++ b/core-bundle/tests/Doctrine/Schema/DcaSchemaProviderTest.php @@ -43,8 +43,11 @@ public function testCreatesASchema(array $dca = [], array $sql = []): void $this->assertTrue($table->getColumn('id')->getNotnull()); $this->assertFalse($table->getColumn('id')->getFixed()); - if (null !== ($default = $table->getColumn('id')->getDefault())) { - $this->assertSame(0, $default); + /** @var int|null $idDefault */ + $idDefault = $table->getColumn('id')->getDefault(); + + if (null !== $idDefault) { + $this->assertSame(0, $idDefault); } $this->assertTrue($table->hasColumn('pid')); @@ -59,8 +62,10 @@ public function testCreatesASchema(array $dca = [], array $sql = []): void $this->assertSame(128, $table->getColumn('title')->getLength()); $this->assertSame('utf8mb4_bin', $table->getColumn('title')->getPlatformOption('collation')); - if (null !== ($default = $table->getColumn('title')->getDefault())) { - $this->assertSame('', $default); + $titleDefault = $table->getColumn('title')->getDefault(); + + if (null !== $titleDefault) { + $this->assertSame('', $titleDefault); } $this->assertTrue($table->hasColumn('uppercase')); @@ -94,7 +99,13 @@ public function testCreatesASchema(array $dca = [], array $sql = []): void $this->assertFalse($table->getColumn('price')->getFixed()); $this->assertSame(6, $table->getColumn('price')->getPrecision()); $this->assertSame(2, $table->getColumn('price')->getScale()); - $this->assertSame(1.99, $table->getColumn('price')->getDefault()); + + /** @var float|null $priceDefault */ + $priceDefault = $table->getColumn('price')->getDefault(); + + if (null !== $priceDefault) { + $this->assertSame(1.99, $priceDefault); + } $this->assertTrue($table->hasColumn('thumb')); $this->assertSame('blob', $table->getColumn('thumb')->getType()->getName()); @@ -119,8 +130,10 @@ public function testCreatesASchema(array $dca = [], array $sql = []): void $this->assertTrue($table->getColumn('published')->getNotnull()); $this->assertTrue($table->getColumn('published')->getFixed()); - if (null !== ($default = $table->getColumn('published')->getDefault())) { - $this->assertSame('', $default); + $publishedDefault = $table->getColumn('published')->getDefault(); + + if (null !== $publishedDefault) { + $this->assertSame('', $publishedDefault); } } diff --git a/core-bundle/tests/Framework/ContaoFrameworkTest.php b/core-bundle/tests/Framework/ContaoFrameworkTest.php index 424d8c83566..f8aeccfa41a 100644 --- a/core-bundle/tests/Framework/ContaoFrameworkTest.php +++ b/core-bundle/tests/Framework/ContaoFrameworkTest.php @@ -491,6 +491,7 @@ public function testRegistersTheLazySessionAccessObject(): void $framework->setContainer($this->getContainerWithContaoConfiguration()); $framework->initialize(); + /* @phpstan-ignore-next-line */ $this->assertInstanceOf(LazySessionAccess::class, $_SESSION); $this->assertInstanceOf(ArrayAttributeBag::class, $_SESSION['BE_DATA']); $this->assertInstanceOf(ArrayAttributeBag::class, $_SESSION['FE_DATA']); diff --git a/core-bundle/tests/Image/Studio/FigureBuilderIntegrationTest.php b/core-bundle/tests/Image/Studio/FigureBuilderIntegrationTest.php index 3574e81ccde..75e455ce474 100644 --- a/core-bundle/tests/Image/Studio/FigureBuilderIntegrationTest.php +++ b/core-bundle/tests/Image/Studio/FigureBuilderIntegrationTest.php @@ -31,6 +31,7 @@ use Contao\System; use Contao\Template; use Imagine\Gd\Imagine as ImagineGd; +use PHPUnit\Framework\MockObject\MockObject; use Psr\Log\NullLogger; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\Filesystem\Filesystem; @@ -1456,7 +1457,7 @@ private function setUpTestCase(\Closure $testCase): array $GLOBALS['TL_HOOKS']['replaceInsertTags'][] = [self::class, 'replaceFileTestInsertTag']; - // Register dummy page + /** @var PageModel&MockObject $page */ $page = $this->mockClassWithProperties(PageModel::class); $page->language = 'en'; diff --git a/core-bundle/tests/Mailer/ContaoMailerTest.php b/core-bundle/tests/Mailer/ContaoMailerTest.php index 4fcdd122350..1eeab781f75 100644 --- a/core-bundle/tests/Mailer/ContaoMailerTest.php +++ b/core-bundle/tests/Mailer/ContaoMailerTest.php @@ -17,6 +17,7 @@ use Contao\CoreBundle\Mailer\TransportConfig; use Contao\CoreBundle\Tests\TestCase; use Contao\PageModel; +use PHPUnit\Framework\MockObject\MockObject; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; use Symfony\Component\Mailer\Mailer; @@ -29,6 +30,7 @@ class ContaoMailerTest extends TestCase { public function testSetsTransportForRequest(): void { + /** @var PageModel&MockObject $pageModel */ $pageModel = $this->mockClassWithProperties(PageModel::class); $pageModel->mailerTransport = 'foobar'; diff --git a/core-bundle/tests/Routing/UrlGeneratorTest.php b/core-bundle/tests/Routing/UrlGeneratorTest.php index d611237d4a9..583bf753f33 100644 --- a/core-bundle/tests/Routing/UrlGeneratorTest.php +++ b/core-bundle/tests/Routing/UrlGeneratorTest.php @@ -248,11 +248,10 @@ public function testDoesNotModifyTheContextIfThereIsAHostname(): void public function testHandlesNonArrayParameters(): void { - /* @phpstan-ignore-next-line */ - $this - ->getUrlGenerator($this->mockRouterWithContext(['alias' => 'foo'])) - ->generate('foo', 'bar') - ; + $generator = $this->getUrlGenerator($this->mockRouterWithContext(['alias' => 'foo'])); + + /* @phpstan-ignore-next-line */ + $generator->generate('foo', 'bar'); } private function getUrlGenerator(UrlGeneratorInterface $router, bool $prependLocale = false, bool $useAutoItem = true): UrlGenerator diff --git a/monorepo.yml b/monorepo.yml index 698fd3fe982..25ea72c3f6e 100644 --- a/monorepo.yml +++ b/monorepo.yml @@ -10,12 +10,12 @@ composer: require-dev: contao/easy-coding-standard: ^2.0 contao/monorepo-tools: dev-master - contao/phpstan: ^0.12 - psalm/plugin-phpunit: ^0.9 + phpstan/phpstan-phpunit: ^0.12 + phpstan/phpstan-symfony: ^0.12 + psalm/plugin-phpunit: ^0.10 psalm/plugin-symfony: ^1.0 slam/phpstan-extensions: ^5.0 - vimeo/psalm: ^3.9 - weirdan/doctrine-psalm-plugin: ^0.10 + weirdan/doctrine-psalm-plugin: ^0.11 repositories: core-bundle: diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 8994dd27801..fd54e3647e7 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -1,5 +1,4 @@ includes: - - vendor/contao/phpstan/extension.neon - vendor/phpstan/phpstan-phpunit/extension.neon - vendor/phpstan/phpstan-phpunit/rules.neon - vendor/phpstan/phpstan-symfony/extension.neon @@ -11,15 +10,13 @@ rules: - TheCodingMachine\PHPStan\Rules\Exceptions\ThrowMustBundlePreviousExceptionRule parameters: - contao: - services_yml_path: %currentWorkingDirectory%/core-bundle/src/Resources/config/services.yml - - symfony: - container_xml_path: %currentWorkingDirectory%/core-bundle/var/cache/phpstan/appContao_CoreBundle_Tests_Functional_app_AppKernelPhpstanDebugContainer.xml - dynamicConstantNames: - BE_USER_LOGGED_IN + universalObjectCratesClasses: + - Contao\Model + - Contao\Template + excludes_analyse: - %currentWorkingDirectory%/core-bundle/src/Resources/* - %currentWorkingDirectory%/core-bundle/tests/Fixtures/* @@ -34,25 +31,9 @@ parameters: - '#Call to an undefined method Symfony\\Component\\Config\\Definition\\Builder\\NodeDefinition::children\(\)\.#' - '#Call to an undefined method Symfony\\Component\\Config\\Definition\\Builder\\NodeDefinition::addDefaultsIfNotSet\(\)\.#' - # Ignore $_SESSION type errors in the lazy session access test - - '#Instanceof between array and Contao\\CoreBundle\\Session\\LazySessionAccess will always evaluate to false\.#' - # Ignore the wrong return type hint of the UrlGeneratorInterface::generate() method - '#Method Contao\\CoreBundle\\Picker\\AbstractPickerProvider::generateUrl\(\) never returns null so it can be removed from the return typehint\.#' - # Ignore constant errors due to bootstrap.php in contao/contao-phpstan (see https://github.com/contao/contao/pull/1451) - - message: '#Call to method PHPUnit\\Framework\\Assert::assert(Same|Null|True|InstanceOf)\(\) with .* will always evaluate to false\.#' - paths: - - %currentWorkingDirectory%/core-bundle/tests/Framework/ContaoFrameworkTest.php - - %currentWorkingDirectory%/core-bundle/tests/Doctrine/Schema/DcaSchemaProviderTest.php - - # Ignore that $container->get() always returns false (see https://github.com/phpstan/phpstan-symfony/issues/74) - - message: '#Negated boolean expression is always (false|true)\.#' - paths: - - %currentWorkingDirectory%/core-bundle/src/Monolog/ContaoTableHandler.php - - %currentWorkingDirectory%/core-bundle/src/DependencyInjection/Compiler/*Pass.php - - %currentWorkingDirectory%/core-bundle/src/Controller/AbstractController.php - treatPhpDocTypesAsCertain: false checkGenericClassInNonGenericObjectType: false inferPrivatePropertyTypeFromConstructor: true diff --git a/psalm.xml b/psalm.xml index 7bb0ffae8ce..31e55ab1d7c 100644 --- a/psalm.xml +++ b/psalm.xml @@ -12,17 +12,6 @@ - -