diff --git a/README.md b/README.md
index f1a85865..24951f2d 100644
--- a/README.md
+++ b/README.md
@@ -13,8 +13,7 @@ Dotkernel web starter package suitable for frontend applications.
[](https://github.com/dotkernel/frontend/actions/workflows/continuous-integration.yml)
[](https://codecov.io/gh/dotkernel/frontend)
[](https://github.com/dotkernel/frontend/actions/workflows/qodana_code_quality.yml)
-
-[](https://insight.symfony.com/projects/a28dac55-3366-4020-9a49-53f6fcbeda4e)
+[](https://github.com/dotkernel/frontend/actions/workflows/static-analysis.yml)
## Installing DotKernel `frontend`
diff --git a/composer.json b/composer.json
index fcb02e3e..103f783a 100644
--- a/composer.json
+++ b/composer.json
@@ -78,8 +78,11 @@
"mezzio/mezzio-tooling": "^2.9.0",
"phpunit/phpunit": "^10.5",
"roave/security-advisories": "dev-master",
- "vimeo/psalm": "^5.21.1",
- "vincentlanglet/twig-cs-fixer": "^2.12"
+ "vincentlanglet/twig-cs-fixer": "^2.12",
+ "phpstan/phpstan": "^2.0",
+ "phpstan/phpstan-doctrine": "^2.0",
+ "phpstan/phpstan-phpunit": "^2.0",
+ "symfony/var-dumper": "^7.1"
},
"autoload": {
"psr-4": {
@@ -107,13 +110,14 @@
"mezzio": "mezzio --ansi",
"check": [
"@cs-check",
- "@test"
+ "@test",
+ "@static-analysis"
],
"clear-config-cache": "php bin/clear-config-cache.php",
"cs-check": "phpcs",
"cs-fix": "phpcbf",
"serve": "php -S 0.0.0.0:8080 -t public/",
- "static-analysis": "psalm --shepherd --stats",
+ "static-analysis": "phpstan analyse",
"test": "phpunit --colors=always",
"test-coverage": "phpunit --colors=always --coverage-clover clover.xml",
"twig-cs-check": "vendor/bin/twig-cs-fixer lint --config=config/twig-cs-fixer.php",
diff --git a/phpstan.neon b/phpstan.neon
new file mode 100644
index 00000000..96ced513
--- /dev/null
+++ b/phpstan.neon
@@ -0,0 +1,21 @@
+includes:
+ - vendor/phpstan/phpstan-doctrine/extension.neon
+ - vendor/phpstan/phpstan-phpunit/extension.neon
+parameters:
+ level: 5
+ paths:
+ - src
+ - test
+ treatPhpDocTypesAsCertain: false
+ ignoreErrors:
+ - '/Parameter #1 \$expected of method PHPUnit\\Framework\\Assert::assertSame\(\) contains unresolvable type\./'
+ -
+ message: '#Call to method PHPUnit\\Framework\\Assert::assertInstanceOf\(\) with .* will always evaluate to true.#'
+ path: test
+ -
+ message: '#Call to an undefined method Laminas\\InputFilter\\InputFilterInterface::getInputs\(\)#'
+ path: test
+ -
+ message: '#Call to an undefined method Laminas\\Authentication\\AuthenticationServiceInterface::getStorage\(\)#'
+ path: src/App/src/Middleware/RememberMeMiddleware.php
+
diff --git a/psalm-baseline.xml b/psalm-baseline.xml
deleted file mode 100644
index e8a04843..00000000
--- a/psalm-baseline.xml
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
- getStorage
- getStorage
-
-
-
-
- getCookieSameSite
-
-
-
-
- iterable
-
-
-
diff --git a/psalm.xml b/psalm.xml
deleted file mode 100644
index ed4c186a..00000000
--- a/psalm.xml
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/src/App/src/Service/CookieService.php b/src/App/src/Service/CookieService.php
index 2fc0def1..dacced87 100644
--- a/src/App/src/Service/CookieService.php
+++ b/src/App/src/Service/CookieService.php
@@ -6,6 +6,7 @@
use Dot\DependencyInjection\Attribute\Inject;
use Laminas\Session\Config\ConfigInterface;
+use Laminas\Session\Config\SameSiteCookieCapableInterface;
use Laminas\Session\SessionManager;
use function setcookie;
@@ -13,7 +14,7 @@
class CookieService implements CookieServiceInterface
{
- private ConfigInterface $sessionConfig;
+ private ConfigInterface|SameSiteCookieCapableInterface $sessionConfig;
#[Inject(SessionManager::class)]
public function __construct(SessionManager $sessionManager)
diff --git a/src/Contact/src/Service/MessageService.php b/src/Contact/src/Service/MessageService.php
index 4847a42d..006faee9 100644
--- a/src/Contact/src/Service/MessageService.php
+++ b/src/Contact/src/Service/MessageService.php
@@ -4,7 +4,6 @@
namespace Frontend\Contact\Service;
-use Doctrine\ORM\EntityRepository;
use Dot\DependencyInjection\Attribute\Inject;
use Dot\Mail\Service\MailServiceInterface;
use Frontend\Contact\Entity\Message;
@@ -28,7 +27,7 @@ public function __construct(
) {
}
- public function getRepository(): MessageRepository|EntityRepository
+ public function getRepository(): MessageRepository
{
return $this->repository;
}
diff --git a/src/Plugin/src/PluginManager.php b/src/Plugin/src/PluginManager.php
index d634f32a..4dc68a63 100644
--- a/src/Plugin/src/PluginManager.php
+++ b/src/Plugin/src/PluginManager.php
@@ -11,6 +11,6 @@
*/
class PluginManager extends AbstractPluginManager
{
- /** @var string $instanceOf */
+ /** @var class-string|null $instanceOf */
protected $instanceOf = PluginInterface::class;
}
diff --git a/src/User/src/Service/UserService.php b/src/User/src/Service/UserService.php
index b32d79cb..93c85720 100644
--- a/src/User/src/Service/UserService.php
+++ b/src/User/src/Service/UserService.php
@@ -275,7 +275,7 @@ public function sendActivationMail(User $user): bool
return $this->mailService->send()->isValid();
}
- public function findOneBy(array $params = []): ?UserInterface
+ public function findOneBy(array $params = []): ?User
{
if (empty($params)) {
return null;
@@ -344,7 +344,7 @@ public function getRepository(): UserRepository
/**
* @throws Exception
*/
- public function addRememberMeToken(UserInterface|User $user, string $userAgent, array $cookies = []): void
+ public function addRememberMeToken(User $user, string $userAgent, array $cookies = []): void
{
$this->deleteExpiredRememberMeTokens();
diff --git a/src/User/src/Service/UserServiceInterface.php b/src/User/src/Service/UserServiceInterface.php
index ae181dea..4eaf646d 100644
--- a/src/User/src/Service/UserServiceInterface.php
+++ b/src/User/src/Service/UserServiceInterface.php
@@ -18,7 +18,7 @@ public function createUser(array $data): UserInterface;
*/
public function sendActivationMail(User $user): bool;
- public function findOneBy(array $params = []): ?UserInterface;
+ public function findOneBy(array $params = []): ?User;
public function activateUser(User $user): User;
@@ -26,7 +26,7 @@ public function findByUuid(string $uuid): ?User;
public function getRepository(): UserRepository;
- public function addRememberMeToken(UserInterface|User $user, string $userAgent, array $cookies = []): void;
+ public function addRememberMeToken(User $user, string $userAgent, array $cookies = []): void;
public function deleteRememberMeToken(array $cookies = []): void;
diff --git a/test/Unit/App/Middleware/RememberMeMiddlewareTest.php b/test/Unit/App/Middleware/RememberMeMiddlewareTest.php
index 8bd96fc6..97c0975c 100644
--- a/test/Unit/App/Middleware/RememberMeMiddlewareTest.php
+++ b/test/Unit/App/Middleware/RememberMeMiddlewareTest.php
@@ -17,15 +17,16 @@
use Laminas\Authentication\AuthenticationService;
use Laminas\Authentication\Exception\ExceptionInterface;
use PHPUnit\Framework\MockObject\Exception;
+use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
class RememberMeMiddlewareTest extends TestCase
{
- private ServerRequestInterface $request;
+ private ServerRequestInterface|MockObject $request;
- private RequestHandlerInterface $handler;
+ private RequestHandlerInterface|MockObject $handler;
/**
* @throws Exception
diff --git a/test/Unit/Plugin/FormsPluginTest.php b/test/Unit/Plugin/FormsPluginTest.php
index 4a64dd07..1fbc1361 100644
--- a/test/Unit/Plugin/FormsPluginTest.php
+++ b/test/Unit/Plugin/FormsPluginTest.php
@@ -37,6 +37,7 @@ public function testWillRestoreState(): void
{
$hash = (new Csrf(['session' => new Container()]))->getHash();
+ /** @var array $oldData */
$oldData = [
'identity' => 'old@identity.com',
'password' => 'old-password',
@@ -155,7 +156,7 @@ public function testWillGetMessages(): void
$this->assertNotEmpty($messagesAsString);
}
- private function getDummyFlashMessenger(): FlashMessengerInterface
+ private function getDummyFlashMessenger(): object
{
return new class implements FlashMessengerInterface {
private array $data = [];