1
0

refactor: fix all 105 PHPStan 2 strict type findings across core and modules

Resolve all non-false-positive PHPStan 2 findings, reducing the baseline
from 486 to 382 entries (only unused-public false positives remain).

Categories fixed:
- Remove 39 redundant type checks (is_string, is_array, is_object, method_exists)
- Remove 12 no-op array_values() on already-sequential lists
- Simplify 13 null-coalesce on guaranteed offsets
- Remove 8 always-true instanceof checks
- Replace 12 redundant test assertions (assertTrue(true) → addToAssertionCount)
- Simplify 6 unnecessary nullsafe operators (?-> → ->)
- Fix 6 always-true !== '' comparisons
- Fix remaining: unset.offset, return.unusedType, staticMethod narrowing

53 files changed across core/, modules/, pages/, and tests/.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-14 12:54:20 +02:00
parent a736566071
commit 3f0db68b27
53 changed files with 90 additions and 640 deletions

View File

@@ -283,7 +283,7 @@ final class ModuleRegistry
// — Merge search resources (fail-fast on duplicate provider) ——
foreach ($manifest->searchResources as $provider) {
if (!is_string($provider) || trim($provider) === '') {
if (trim($provider) === '') {
throw new RuntimeException(
"Search resource provider in module '{$manifest->id}' must be a non-empty class-string."
);
@@ -333,7 +333,7 @@ final class ModuleRegistry
// — Merge layout context providers ————————————————
foreach ($manifest->layoutContextProviders as $providerClass) {
if (!is_string($providerClass) || trim($providerClass) === '') {
if (trim($providerClass) === '') {
throw new RuntimeException(
"Layout context provider in module '{$manifest->id}' must be a non-empty class-string."
);
@@ -343,7 +343,7 @@ final class ModuleRegistry
// — Merge session providers ——————————————————————
foreach ($manifest->sessionProviders as $providerClass) {
if (!is_string($providerClass) || trim($providerClass) === '') {
if (trim($providerClass) === '') {
throw new RuntimeException(
"Session provider in module '{$manifest->id}' must be a non-empty class-string."
);
@@ -353,7 +353,7 @@ final class ModuleRegistry
// — Merge authorization policies (fail-fast on duplicate) ———
foreach ($manifest->authorizationPolicies as $policyClass) {
if (!is_string($policyClass) || trim($policyClass) === '') {
if (trim($policyClass) === '') {
throw new RuntimeException(
"Authorization policy in module '{$manifest->id}' must be a non-empty class-string."
);
@@ -402,7 +402,7 @@ final class ModuleRegistry
'default_schedule_time' => $schedulerJob['default_schedule_time'],
'default_schedule_weekdays_csv' => $schedulerJob['default_schedule_weekdays_csv'],
'default_catchup_once' => (int) $schedulerJob['default_catchup_once'],
'allowed_schedule_types' => array_values($schedulerJob['allowed_schedule_types']),
'allowed_schedule_types' => $schedulerJob['allowed_schedule_types'],
'module_id' => $manifest->id,
];
}
@@ -637,10 +637,10 @@ final class ModuleRegistry
/** @return list<string> */
public function getPermissionKeys(): array
{
return array_values(array_map(
return array_map(
static fn (array $permission): string => (string) $permission['key'],
$this->mergedPermissions
));
);
}
/** @return list<class-string> */

View File

@@ -34,9 +34,6 @@ final class ModuleRuntimeAssetPublisher
$desired = [];
foreach ($modules as $manifest) {
if (!$manifest instanceof ModuleManifest) {
continue;
}
$moduleWebDir = rtrim($manifest->basePath, '/') . '/web';
if (!is_dir($moduleWebDir)) {
continue;