Files
michaelschiemer/src/Framework/Design/Analyzer/DesignSystemAnalyzer.php
Michael Schiemer 55a330b223 Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug
- Add DISCOVERY_SHOW_PROGRESS=true
- Temporary changes for debugging InitializerProcessor fixes on production
2025-08-11 20:13:26 +02:00

175 lines
6.4 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Framework\Design\Analyzer;
use App\Framework\Design\Parser\CssParser;
use App\Framework\Design\ValueObjects\CssParseResult;
use App\Framework\Filesystem\FilePath;
/**
* Haupt-Analyzer für das Design System
*/
final readonly class DesignSystemAnalyzer
{
public function __construct(
private CssParser $cssParser = new CssParser(),
private TokenAnalyzer $tokenAnalyzer = new TokenAnalyzer(),
private ComponentDetector $componentDetector = new ComponentDetector(),
private ConventionChecker $conventionChecker = new ConventionChecker(),
private ColorAnalyzer $colorAnalyzer = new ColorAnalyzer()
) {
}
/**
* Analysiert ein komplettes Design System
*/
public function analyzeDesignSystem(string|array $cssFiles): DesignSystemAnalysis
{
$files = is_array($cssFiles) ? $cssFiles : [$cssFiles];
$parseResults = [];
// Parse alle CSS-Dateien
foreach ($files as $file) {
$filePath = $file instanceof FilePath ? $file : FilePath::create($file);
$parseResults[] = $this->cssParser->parseFile($filePath);
}
// Kombiniere alle Ergebnisse
$combinedResult = $this->combineParseResults($parseResults);
// Durchführung der verschiedenen Analysen
$tokenAnalysis = $this->tokenAnalyzer->analyze($combinedResult);
$componentAnalysis = $this->componentDetector->detectComponents($combinedResult);
$conventionAnalysis = $this->conventionChecker->checkConventions($combinedResult);
$colorAnalysis = $this->colorAnalyzer->analyzeColors($combinedResult);
return new DesignSystemAnalysis(
sourceFiles: array_map(fn ($result) => $result->sourceFile, $parseResults),
parseResults: $parseResults,
combinedResult: $combinedResult,
tokenAnalysis: $tokenAnalysis,
componentAnalysis: $componentAnalysis,
conventionAnalysis: $conventionAnalysis,
colorAnalysis: $colorAnalysis,
overallStatistics: $this->calculateOverallStatistics($parseResults)
);
}
/**
* Analysiert ein einzelnes CSS-Verzeichnis
*/
public function analyzeDirectory(string $directory, bool $recursive = true): DesignSystemAnalysis
{
$parseResults = $this->cssParser->parseDirectory($directory, $recursive);
if (empty($parseResults)) {
throw new \InvalidArgumentException("No CSS files found in directory: $directory");
}
$combinedResult = $this->combineParseResults($parseResults);
return new DesignSystemAnalysis(
sourceFiles: array_map(fn ($result) => $result->sourceFile, $parseResults),
parseResults: $parseResults,
combinedResult: $combinedResult,
tokenAnalysis: $this->tokenAnalyzer->analyze($combinedResult),
componentAnalysis: $this->componentDetector->detectComponents($combinedResult),
conventionAnalysis: $this->conventionChecker->checkConventions($combinedResult),
colorAnalysis: $this->colorAnalyzer->analyzeColors($combinedResult),
overallStatistics: $this->calculateOverallStatistics($parseResults)
);
}
/**
* Schnelle Analyse nur für Statistiken
*/
public function quickAnalyze(string|array $cssFiles): array
{
$files = is_array($cssFiles) ? $cssFiles : [$cssFiles];
$statistics = [];
foreach ($files as $file) {
$filePath = $file instanceof FilePath ? $file : FilePath::create($file);
$result = $this->cssParser->parseFile($filePath);
$statistics[] = $result->getStatistics();
}
return $statistics;
}
/**
* Kombiniert mehrere Parse-Ergebnisse zu einem Gesamt-Ergebnis
*/
private function combineParseResults(array $parseResults): CssParseResult
{
if (empty($parseResults)) {
throw new \InvalidArgumentException('No parse results to combine');
}
if (count($parseResults) === 1) {
return $parseResults[0];
}
$allRules = [];
$allCustomProperties = [];
$allClassNames = [];
$combinedContent = '';
foreach ($parseResults as $result) {
$allRules = array_merge($allRules, $result->rules);
$allCustomProperties = array_merge($allCustomProperties, $result->customProperties);
$allClassNames = array_merge($allClassNames, $result->classNames);
$combinedContent .= $result->rawContent . "\n";
}
return new CssParseResult(
sourceFile: null, // Combined result has no single source
rules: $allRules,
customProperties: $allCustomProperties,
classNames: $allClassNames,
rawContent: $combinedContent
);
}
/**
* Berechnet Gesamt-Statistiken für alle Dateien
*/
private function calculateOverallStatistics(array $parseResults): array
{
$totalStats = [
'total_files' => count($parseResults),
'total_rules' => 0,
'total_selectors' => 0,
'total_properties' => 0,
'total_design_tokens' => 0,
'total_class_names' => 0,
'total_content_size' => 0,
'file_breakdown' => [],
];
foreach ($parseResults as $result) {
$stats = $result->getStatistics();
$totalStats['total_rules'] += $stats['total_rules'];
$totalStats['total_selectors'] += $stats['total_selectors'];
$totalStats['total_properties'] += $stats['total_properties'];
$totalStats['total_design_tokens'] += $stats['design_tokens'];
$totalStats['total_class_names'] += $stats['class_names'];
$totalStats['total_content_size'] += $stats['content_size_bytes'];
$totalStats['file_breakdown'][] = $stats;
}
// Durchschnittliche Werte berechnen
$fileCount = max(1, count($parseResults));
$totalStats['avg_rules_per_file'] = round($totalStats['total_rules'] / $fileCount, 2);
$totalStats['avg_properties_per_file'] = round($totalStats['total_properties'] / $fileCount, 2);
$totalStats['avg_tokens_per_file'] = round($totalStats['total_design_tokens'] / $fileCount, 2);
$totalStats['avg_classes_per_file'] = round($totalStats['total_class_names'] / $fileCount, 2);
return $totalStats;
}
}