diff --git a/CHANGELOG.md b/CHANGELOG.md
index 66510b725..8139973aa 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,8 @@ und dieses Projekt folgt [Semantic Versioning](https://semver.org/lang/de/).
- `RexStan::startBackgroundWebAnalysis()` spawnt den PHPStan-Lauf detached (Unix: `shell_exec('(...) &')`, Windows: `start /B`); Ergebnis wird atomar (erst in eine Temp-Datei, dann per `mv`/`move`) an seinen finalen Pfad geschrieben, damit ein Poller nie eine unvollständige Ergebnisdatei zu sehen bekommt.
- `RexResultsRenderer::renderAnalysisBody()` extrahiert die bisher direkt in `pages/analysis.php` liegende Rendering-Logik in eine wiederverwendbare Methode, die sowohl beim normalen Seitenaufruf (gecachtes Ergebnis) als auch von der Ajax-Statusabfrage (frisches Ergebnis) genutzt wird.
+- **Hinweis auf niedrigeres Level bei sehr vielen Ergebnissen**: Liefert ein Lauf mehr als 200 Probleme, erscheint ein Hinweis, in den Einstellungen ein niedrigeres Level zu wählen und sich von dort schrittweise nach oben zu arbeiten. PHPStan-Level sind selbst bereits eine Priorisierung nach Strenge (jede Stufe baut auf den Prüfungen aller niedrigeren Stufen auf).
+
### 🧹 Code Quality
- `RexStan::runFromWeb()`'s Interpretation der rohen PHPStan-Ausgabe (JSON vs. Klartext-Fehler) in `RexStan::interpretAnalysisOutput()` extrahiert, damit sowohl der synchrone als auch der neue Hintergrund-Pfad dieselbe Logik nutzen.
diff --git a/lib/RexResultsRenderer.php b/lib/RexResultsRenderer.php
index a58f78885..5db20ad0a 100644
--- a/lib/RexResultsRenderer.php
+++ b/lib/RexResultsRenderer.php
@@ -15,6 +15,11 @@
final class RexResultsRenderer
{
+ // Heuristic threshold for the "consider a lower level" hint below - not a
+ // hard science, just meant to catch the "way too much to work through at
+ // once" case (e.g. jumping straight to level 10 with every extra rule set).
+ private const MANY_ERRORS_HINT_THRESHOLD = 200;
+
/**
* Renders the full analysis result body - the same markup pages/analysis.php
* used to produce synchronously, now as a reusable string so it can also be
@@ -131,10 +136,25 @@ public static function renderAnalysisBody($phpstanResult, bool $regenerateBaseli
echo rex_view::error('Nicht alle Fehler konnten ignoriert werden. Empfehlung: Die verbliebenen kritischen Fehler analysieren und beheben.');
}
+ $level = RexStanUserConfig::getLevel();
+
echo rex_view::warning(
- 'Level-'.RexStanUserConfig::getLevel().'-Analyse: '. $totalErrors .' Probleme gefunden in '. count($phpstanResult['files']) .' Dateien.'. $baselineButton. $baselineInfo
+ 'Level-'.$level.'-Analyse: '. $totalErrors .' Probleme gefunden in '. count($phpstanResult['files']) .' Dateien.'. $baselineButton. $baselineInfo
);
+ // PHPStan's levels are themselves already a priority ordering (stricter
+ // levels build on the checks of every level below them) - rather than
+ // inventing a second, parallel priority scheme on top, a level this
+ // noisy is better addressed by choosing a lower level first and working
+ // back up, so just point at that existing lever instead.
+ if ($totalErrors > self::MANY_ERRORS_HINT_THRESHOLD && $level > 0) {
+ echo rex_view::info(
+ 'Das sind sehr viele Ergebnisse auf einmal. Da PHPStan-Level bereits eine Priorisierung nach Strenge sind, '
+ .'lohnt es sich meist mehr, in den Einstellungen '
+ .'zunächst ein niedrigeres Level zu wählen und sich von dort aus nach oben zu arbeiten.'
+ );
+ }
+
foreach ($phpstanResult['files'] as $file => $fileResult) {
$linkFile = preg_replace('/\s\(in context.*?$/', '', $file);
if ($linkFile === null) {